Arduino knippert morse

Ik ben nog bezig om C++ te leren.
Ik heb een programma gemaakt dat de LED op pin 13 een woord laten morsen.Code hieronder.
Maar ik zou graag een database maken waarin alle morsecodes staan, zodanig dat ik maar een woord of zin op een regel moet programmeren om dat woord dan te morsen op pin 13.
Bijkomende vraag: hoe lang duurt een spatie tussen 2 tekens en tussen 2 woorden met als ref de lengte van een punt? En hou lang duurt een streep?

c code:


  // put your setup code here, to run once:
  pinMode(13, OUTPUT);
  int a;

}

void loop() {
    
{
  //Begin met pauze
  digitalWrite(13, LOW);
  delay(2000);
  // 3 puntjes: S
  digitalWrite(13, HIGH);
  delay(300);
  digitalWrite(13, LOW);
  delay(300); 
  digitalWrite(13, HIGH);
  delay(300);
  digitalWrite(13, LOW);
  delay(300);
  digitalWrite(13, HIGH);
  delay(300);
  digitalWrite(13, LOW);
  delay(900);
  // Streep: T
  digitalWrite(13, HIGH);
  delay(900);
  digitalWrite(13, LOW);
  delay(900);
  //punt streep: A
  digitalWrite(13, HIGH);
  delay(300);
  digitalWrite(13, LOW);
  delay(300);
  digitalWrite(13, HIGH);
  delay(900);
  digitalWrite(13, LOW);
  delay(900);
  // streep punt: N
  digitalWrite(13, HIGH);
  delay(900);
  digitalWrite(13, LOW);
  delay(300);
  digitalWrite(13,HIGH);
  delay(300);
  digitalWrite(13,LOW);
  delay(300);
  
  
  
  
  }
  }
  

[Bericht gewijzigd door Henry S. op 13 mei 2019 22:47:32 (0%)]

Nihil est verum, quod non probatur primo.
pa3gws

Golden Member

Ik ben gestopt met roken nu mijn schakelingen nog.

Er is in Morsecode geen vastgelegde norm voor de snelheid, enkel de verhoudingen zijn belangrijk. Gekopieerd van de Engelstalige Wikipedia:

The duration of a dash is three times the duration of a dot. Each dot or dash within a character is followed by period of signal absence, called a space, equal to the dot duration. The letters of a word are separated by a space of duration equal to three dots, and the words are separated by a space equal to seven dots.

Wat uw code betreft: begin met een routine ("functie") te maken voor elk weer te geven karakter; het hoofdprogramma wordt dan iets in de trant van

code:

for char in text_to_transmit
 case char
  'A'  morse_A
  'B'  morse_B
 esac

In assembler zou je zelfs een tabel kunnen maken met de adressen van de morse_[a-z] functies, en dan een 'jump indirect' op basis van de ascii-code... In C kan dat misschien ook wel maar het gaat mijn petje ver te boven.

hoe beter de vraag geschreven, zoveel te meer kans op goed antwoord

TS, je programmeert in "C" en geen "C++". Dat laatste is ongebruikelijk op een Arduino. Maar dat terzijde.

Voor je code kun je het beste een tabel maken waar alle karakters in staan. Maak bv gebruik van het feit dat ascii karakters allemaal een opvolgende ascii code hebben. Die kun je dan als index in je tabel gebruiken. In de tabel staat dan de ./- combinatie. Met een functie zoek je de juiste code bij het juiste karakter. Even in vogelvlucht :-)
Maar he, er zijn vast legio voorbeelden te vinden die je een mooie start geven.
[edit] Nou vooruit, een linkje:
https://www.codeproject.com/Articles/1250929/Sending-Morse-C...ur-Arduino

"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein

@flipflop,

Arduino en Atmel studio werken met de GCC compiler. Die ondersteunt wel degelijk volledig C++. Dezelfde compiler wordt ook voor Linux systemen gebruikt. Alle classen, inheritance, templates is allemaal aanwezig, geen enkel probleem.

Er zijn alleen wel beperkingen tgv het minimale geheugen in de processors en het ontbreken van memory management. Daardoor wordt de STL library wat lastig. Maar ook die is wel degelijk beschikbaar als je wilt.

Op 13 mei 2019 20:04:15 schreef flipflop:
TS, je programmeert in "C" en geen "C++". Dat laatste is ongebruikelijk op een Arduino.

Nou, de classes vliegen je anders om de oren zo gauw je kijkt wat er in die standaard arduino libraries zit...

Maargoed...

als je nou eens:

c code:


punt(){
digitalwrite(dinges, hoog);
delay(kort);
}
streep(){
digitalwrite(dinges, hoog);
delay(lang);
}

SeinLetter(char DeLetter){

 select(DeLetter){
 case 'A':
 punt();
 streep();
 break;
 case 'B'
 streep();
 punt();
 punt();
 punt();
 break;
 //...
 case 'Z'
 streep();
 streep();
 punt();
 punt();
 break;
 default:
 for(uint8_t i=0; i<10; i++){ punt(); };
 break;
}
}

Seintekst(char[]){
 // for item in char SeinLetter(item)
}

ofzo doet. Waarbij je voor seintekst() ofwel met strlength oid aan de gang moet, ofwel de lengte moet meegeven (met risico op buffer overflows en andere narigheid), ofwel moet uitzoeken hoe iterators werken (Als arduino dat tenminste lust, nooit geprobeerd).

In plaats van een select...case een look-up-table kan natuurlijk ook, wat bfm zegt dus. (rew zal zo wel komen uitleggen hoe een LUT in C werkt, hij volgt me opvallend vaak op met een "betere" oplossing in programmeertopics. Maar gewoon een array en een index is in feite ook een LUT. Dan moet je dus alleen nog vertalen tussen je ASCII karakter en je array-index. Index begint op 0, en (DeLetter - 'A') dat is een minteken, geen tekst-streepje begint ook op 0. Alvast handiger dan de array precies op adres 'A' tot ' Z' in het geheugen stoppen. Al kan dat vast ook als je de linker weet te overtuigen met de juiste magische spreuken... Ik zou gewoon een array nemen, dat is makkelijker.)

Maar, elk karakter is meer dan 1 punt of streep. Nuja, behalve de E respectievelijk de T, maar voor de rest zul je toch meer dan 1 adres in je array/LUT nodig hebben. Wat het weer lastig indexeren maakt, omdat je niet steeds "1 verder" kunt. Of zelfs uberhaupt een vaste hoeveelheid verder, want het aantal punten/strepen is ook nog eens verschillend tussen de letters. Dus dan wordt het een array/LUT met functiepointers (want die hebben wel een vaste lengte). Die dan wijzen naar 1 functie per letter. Ja dat kan, maar dan is een select()-case toch ècht overzichtelijker IMHO.

(Hmm, kan het op nog meer manieren? Een soort omgekeerde dichotomische tabel, wellicht... Beginnen met E of T, dan (I of A) of (M of N), en zo verder... Lijkt me ook nodeloos ingewikkeld)

Eluke.nl // Backwards Lightspeed Bus: i*i=-1, so iic=-c.

Op 13 mei 2019 22:25:55 schreef deKees:
Arduino en Atmel studio werken met de GCC compiler. Die ondersteunt wel degelijk volledig C++.

Goh, hmm, tja, zo... :-)

Toch zie je in Arduino code nooit c++ constructies en wel in libraries. Is daar een reden voor?

"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Henry S.

Moderator

Vanwege de doelgroep?
Dit was me ook al eens opgevallen.

73's de PA2HS - ik ben een radiohead, De 2019 CO labvoeding.

Zo! Het is gelukt.
Iedereen dank voor het helpen.
@PA3GWS. Tnkx OM. Jouw link heeft me goed geholpen. Ik had er foutjes in maar heb ze kunnen verbeteren.

Nihil est verum, quod non probatur primo.
pa3gws

Golden Member

Mooi dat het is gelukt maar we willen natuurlijk wel een keertje het resultaat zien/horen. ;-)

Ik ben gestopt met roken nu mijn schakelingen nog.

U vraagt, wij draaien.
We zijn bij de radioamateurs (MCL) Arduino aan het leren.
Daar heb ik dat voor gemaakt.

Nihil est verum, quod non probatur primo.

Leuke oplossing zo. De morse code buitengewoon zichtbaar, mooi.

De '\0' in de morse-tabel kun je trouwens wel weglaten want die komt vanzelf al achter elke string. Nu staat die er telkens 2 keer.