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=c...&projectid=285

Code:
/**
 *  @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.