PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : NIBObee Morsecode via LEDs + Motorsound



nibo
22.10.2011, 23:45
Hallo,

habe eben mein erstes kleines Programm für den NIBObee noch etwas optimiert und online gestellt:

Ein Text wird in Morsecode enkodiert und über die LEDs und Motorsound ausgegeben. Die Tonfrequenz ist über die Fühler einstellbar. (Siehe Projektbeschreibung).

Das Projekt ist auch auf roboter.cc verfügbar: http://roboter.cc/index.php?option=com_nicaiwci&view=project&projectid=285



/**
* @brief Encode a message into morse code.
* Output the code via the LEDs and the motor as sound-generator.
* Push the left sensor to switch sound-output on/off.
* Push the right sensor to modify the sound frequency.
*
* Example: "SOS" will be translated to ...---...
*
* . = dit = short signal = base for morse code timing
* - = dah = long signal = 3 dits long
*
* @author Oliver G.
* @date 2011-10-13
* @version 1.0
*/
#include <nibobee/iodefs.h>
#include <nibobee/led.h>
#include <nibobee/delay.h>
#include <nibobee/sens.h>
#include <nibobee/motpwm.h>


#define DIT_TIME 70 // length of one dit in ms
#define BEEPER_VOLUME 1000 // sound volume roughly grows with speed of motors, 0..1024

char *message = " SOS SOS NIBObee requests your attention. SOS SOS ";

volatile uint8_t beeperActive;
volatile uint8_t signalHigh;
volatile uint16_t ms; // milli seconds counter
volatile uint16_t s; // seconds counter

char* encodeMorseSign(char c);
void outputMorseSign(char* morseSign);
void setSignalHigh(int highTime);
void initBeeper();
void listenSensorInput();


/**
* Output message in a loop by using the LEDs and motor-sound.
*/
int main() {
led_init();
sens_init();
motpwm_init();
initBeeper(); // (i prefer camel case naming...)

while (s < 4) {led_set(s, 1);} // visualize 4 seconds to check timing of one second

char *origMessagePos = message;
while (1) {

while (*message != '\0') {
char* morseSign = encodeMorseSign(*message++);
outputMorseSign(morseSign);
}
message = origMessagePos;
}
}


void initBeeper() {
// config timer 0
TCCR0 = (1<<WGM01); // set CTC modus
TCCR0 |= (1<<CS02); // set prescaler to 256

// set compare value which will trigger interrupt
OCR0 = (F_CPU/256)/1000 -1; // ((15000000/256)/1000) ~= 58.6

// allow compare Interrupt
TIMSK |= (1<<OCIE0);

// activate global interrupts
sei();
beeperActive = 1;
}


/**
* Compare Interrupt Handler
* Is called if TCNT0 = OCR0, about every 1 ms
*/
ISR (TIMER0_COMP_vect) {

if(++ms == 1000) {
s++;
ms = 0;
}

if (beeperActive && signalHigh) {
// let the motor turn left and right quickly to create some noise
// we need 2ms for one period - so we get a tone with ca. 500 Hz
if (ms % 2 == 0) {
motpwm_setRight(BEEPER_VOLUME);
}
else {
motpwm_setRight(-BEEPER_VOLUME);
}
} else {
motpwm_setRight(0);
}
}


void listenSensorInput() {
if (sens_getLeft()) {
beeperActive = beeperActive == 1 ? 0 : 1;
while(sens_getLeft());
}
if (sens_getRight()) {
OCR0 += 10*sens_getRight(); // modify frequency of sound output
while(sens_getRight());
}
}


/**
* Set the output signal for a single morse sign.
* Example: short on, short off, long on = .- = (encoded letter 'a')
*/
void outputMorseSign(char* morseSign) {

while (*morseSign != '\0') {
listenSensorInput();

switch (*morseSign++) {
case '.': setSignalHigh(DIT_TIME); break; // dit
case '-': setSignalHigh(3*DIT_TIME); break; // dah = 3*dit length
default: delay(4*DIT_TIME); break; // 4 + (2 + 1) = 7 dits pause between words
}

delay(DIT_TIME); // 1 dit pause after symbols
}
delay(2*DIT_TIME); // 2 + 1 = 3 dits = 1 dah pause between letters
}


void setSignalHigh(int highTime) {
signalHigh = 1;
for(int ledNr = 0; ledNr < 4; ledNr++) led_set(ledNr, 1);

delay(highTime);

for(int ledNr = 0; ledNr < 4; ledNr++) led_set(ledNr, 0);
signalHigh = 0;
}


/**
* Encode char signs/letters into morse code signs.
*
* Maybe implemented with advantage as an lookup-table/array, e.g. if you need to decode etc.
*/
char* encodeMorseSign(char c) {
// to operate case-insensitive, convert upper case to lower case
if (c >= 'A' && c <= 'Z') {
c += 0x20;
}

switch(c) {
case 'a': return ".-";
case 'b': return "-...";
case 'c': return "-.-.";
case 'd': return "-..";
case 'e': return ".";
case 'f': return ".._.";
case 'g': return "--.";
case 'h': return "....";
case 'i': return "..";
case 'j': return ".---";
case 'k': return "-.-";
case 'l': return ".-..";
case 'm': return "--";
case 'n': return "-.";
case 'o': return "---";
case 'p': return ".--.";
case 'q': return "--.-";
case 'r': return ".-.";
case 's': return "...";
case 't': return "-";
case 'u': return "..-";
case 'v': return "...-";
case 'w': return ".--";
case 'x': return "-..-";
case 'y': return "-.--";
case 'z': return "--..";
case '.': return ".-.-.-."; // . = AAA
case ',': return "--..--"; // , = MIM
case ' ': return " "; // pause between words
// you can complete morse alphabet here
}
return ""; // ignore unkown signs
}

Viel Spaß und schöne Grüße,
Oliver G.