2017-08-09 94 views
-6

我有两个与下面的代码有关的问题。首先,我明白这个代码是可怕的,可以减少和改进。我希望能够添加整个字母和数字,但是输入每一个字母都是愚蠢的。如何让此代码更高效?

第一个问题:如何缩短这段代码?我对数组并不是很熟悉,但我猜这就是我将要使用的。

第二个问题:如何使用数组来表示每个字母/数字?

谢谢大家。

/* 
Blinks "BRENTON" in Morse Code, in pin # 12. 
*/ 

void setup() { 
    // initialize the digital pin as an output. 
    // Pin 13 has an LED connected on most Arduino boards: 
    pinMode(12, OUTPUT); 
    pinMode(13, OUTPUT); 
} 

int dot = 250; 
int dash = dot * 3; 
int space = dot * 7; 
int rest = 250; 

void A() { 
    digitalWrite(12, HIGH); 
    delay(dot); 
    digitalWrite(12, LOW); 
    delay(rest); 
    digitalWrite(12, HIGH); 
    delay(dash); 
    digitalWrite(12, LOW); 
    delay(space); 
} 
void B() { 
    digitalWrite(12, HIGH); 
    delay(dash); 
    digitalWrite(12, LOW); 
    delay(rest); 
    digitalWrite(12, HIGH); 
    delay(dot); 
    digitalWrite(12, LOW); 
    delay(rest); 
    digitalWrite(12, HIGH); 
    delay(dot); 
    digitalWrite(12, LOW); 
    delay(rest); 
    digitalWrite(12, HIGH); 
    delay(dot); 
    digitalWrite(12, LOW); 
    delay(space); 
} 
void R() { 
    digitalWrite(12, HIGH); 
    delay(dot); 
    digitalWrite(12, LOW); 
    delay(rest); 
    digitalWrite(12, HIGH); 
    delay(dash); 
    digitalWrite(12, LOW); 
    delay(rest); 
    digitalWrite(12, HIGH); 
    delay(dot); 
    digitalWrite(12, LOW); 
    delay(space); 
} 
void E() { 
    digitalWrite(12, HIGH); 
    delay(dot); 
    digitalWrite(12, LOW); 
    delay(space); 
} 
void N() { 
    digitalWrite(12, HIGH); 
    delay(dash); 
    digitalWrite(12, LOW); 
    delay(rest); 
    digitalWrite(12, HIGH); 
    delay(dot); 
    digitalWrite(12, LOW); 
    delay(space); 
} 
void T() { 
    digitalWrite(12, HIGH); 
    delay(dash); 
    digitalWrite(12, LOW); 
    delay(space); 
} 
void O() { 
    digitalWrite(12, HIGH); 
    delay(dash); 
    digitalWrite(12, LOW); 
    delay(rest); 
    digitalWrite(12, HIGH); 
    delay(dash); 
    digitalWrite(12, LOW); 
    delay(rest); 
    digitalWrite(12, HIGH); 
    delay(dash); 
    digitalWrite(12, LOW); 
    delay(space); 
} 
void pin13(){ 
    digitalWrite(13, HIGH); 
    delay(10000); 
    digitalWrite(13, LOW); 
    delay(1000); 
} 
void loopOne() { 
    int i = 0; 
    while(i < 100) { 
    pin13(); 
    i++; 
    } 
} 

void loop() { 
    B(); 
    R(); 
    E(); 
    N(); 
    T(); 
    O(); 
    N(); 
} 
+2

你应该问[这里](https://codereview.stackexchange.com/questions) –

+0

请你只是谷歌 “的Arduino莫尔斯” ......它不是那么困难的https://gist.github .com/madc/4474559和其他命中将给予足够的灵感 – Piglet

+1

我投票结束这个问题作为题外话,因为要求改进工作代码的问题属于代码审查,而不是Stack Overflow。 – TylerH

回答

1

几年前,我写了一个摩尔斯电码发生器,用于一个朋友进入地理寻宝。这段代码控制着一台变送器虽然它在C中,但它可能会让你对如何做到这一点有所了解。你真的只需要三个例程,一个用于'dit','dah'和'空间'。

play_space真的只是关闭声音和短暂的延迟。

play_mark真的不过是打开持续时间的声音,并且可以在Arduino中编码为tone(pin, frequency, duration_milliseconds)

init中的所有东西只是设置控制器以设定的频率播放音调。再一次,更容易与Arduino tone()。主要是在MCode结构和它们的数组中表示每个字符和数字。然后,对于要发送的字符串中的每个字符,只需搜索数组,直到找到匹配的字符,然后使用xmit_symbol()从结构中播放code

#define F_CPU 1000000 
#include <avr/io.h> 
#include <util/delay.h> 

// transmission lengths, in milliseconds 
#define DIT_MS 60      // dit length of 120 should yield ~10 words per minute 
#define DAH_MS (DIT_MS * 3)  // dah length 
#define AL_SPACE (DIT_MS * 3) // after-letter space 
#define AW_SPACE (DIT_MS * 6) // after-word space = 6 + after-letter space = 7 

// simple diagnostic LED 
#define LED_1 PA0 

// hardcoded callsign 
const char* CALLSIGN = "HELLO WORLD"; 

static const struct 
{ 
    const char symbol; 
    const uint8_t length; 
    const uint8_t code; 

} MCode[] = 
{ 
    {'A', 2, 0b01000000}, 
    {'B', 4, 0b10010000}, 
    {'C', 4, 0b10100000}, 
    {'D', 3, 0b10000000}, 
    {'E', 1, 0b00000000}, 
    {'F', 4, 0b00100000}, 
    {'G', 3, 0b11000000}, 
    {'H', 4, 0b00000000}, 
    {'I', 2, 0b00000000}, 
    {'J', 4, 0b01110000}, 
    {'K', 3, 0b10100000}, 
    {'L', 4, 0b01000000}, 
    {'M', 2, 0b11000000}, 
    {'N', 2, 0b10000000}, 
    {'O', 3, 0b11100000}, 
    {'P', 4, 0b01100000}, 
    {'Q', 4, 0b11010000}, 
    {'R', 3, 0b01000000}, 
    {'S', 3, 0b00000000}, 
    {'T', 1, 0b10000000}, 
    {'U', 3, 0b00100000}, 
    {'V', 4, 0b00010000}, 
    {'W', 3, 0b01100000}, 
    {'X', 4, 0b10010000}, 
    {'Y', 4, 0b10110000}, 
    {'Z', 4, 0b11000000}, 
    {'1', 5, 0b01111000}, 
    {'2', 5, 0b00111000}, 
    {'3', 5, 0b00011000}, 
    {'4', 5, 0b00001000}, 
    {'5', 5, 0b00000000}, 
    {'6', 5, 0b10000000}, 
    {'7', 5, 0b11000000}, 
    {'8', 5, 0b11100000}, 
    {'9', 5, 0b11110000}, 
    {'0', 5, 0b11111000}, 
    {'-', 6, 0b10000100} 
}; 


void init(void) 
{ 
    // set up diagnostic led 
    DDRA |= (1<<LED_1); 
    // set up OC1A pin as output for PWM signal 
    DDRB |= (1<<PB1); 
    // set up fast PWM mode 
    TCCR1A |= (1<<PWM1A); 
    // timer1 prescaler 
    TCCR1B |= (1<<CS12); // 1/8 (yields ~490Hz at 1MHz FCPU) (p.117) 
    // set OCR value to achieve close enough to square wave 
    OCR1A = 128; 
} 

///////////////////////////////////////////////////////////////////////////////// 
//// ROUTINES TO CREATE MARKS AND SPACES 
///////////////////////////////////////////////////////////////////////////////// 
void play_space(uint16_t length) 
{ 
    // play a space of the specified length 
    PORTA &= ~(1<<LED_1); 
    TCCR1A &= ~(1<<COM1A1); 
    _delay_ms(length); 
} 

void play_mark(uint16_t length) 
{ 
    // play a mark for specified length 
    PORTA |= (1<<LED_1); 
    TCCR1A |= (1<<COM1A1); 
    _delay_ms(length); 
    // always play a dit-length space afterwards 
    PORTA &= ~(1<<LED_1); 
    TCCR1A &= ~(1<<COM1A1); 
    _delay_ms(DIT_MS); 
} 
///////////////////////////////////////////////////////////////////////////////// 



///////////////////////////////////////////////////////////////////////////////// 
//// TRANSMIT A CHARACTER AND INTER-CHARACTER SPACE 
///////////////////////////////////////////////////////////////////////////////// 
void xmit_symbol(uint8_t length, uint8_t code) 
{ 
    for (uint8_t p = 0; p < length; p++) 
    { 
     uint8_t shift = 7 - p; 
     uint8_t mask = 1<<shift; 
     uint8_t result = code & mask; 
     if (result == mask) 
      play_mark(DAH_MS); 
     else 
      play_mark(DIT_MS); 
    } 
    play_space(AL_SPACE); 
} 
///////////////////////////////////////////////////////////////////////////////// 



///////////////////////////////////////////////////////////////////////////////// 
//// TRANSMIT A NULL-TERMINATED STRING 
///////////////////////////////////////////////////////////////////////////////// 
void xmit_callsign() 
{ 
    uint8_t iStringPos; 
    uint8_t iSearchPos; 

    // Process each character of the callsign string. 
    // NOTE: Trick here uses null terminator on string to make comparison false. 
    for (iStringPos = 0; CALLSIGN[iStringPos]; iStringPos++) 
    { 
     // Linear search through array of structs seeking matching symbol. 
     for (iSearchPos = 0; iSearchPos < (sizeof MCode/sizeof *MCode); iSearchPos++) 
     { 
      if (CALLSIGN[iStringPos] == MCode[iSearchPos].symbol) 
      { 
       // We found a match, so transmit this character/symbol. 
       xmit_symbol(MCode[iSearchPos].length, MCode[iSearchPos].code); 

       // Bail out and move on down the string until done... 
       break; 
      } 
     } 
    } 
} 
///////////////////////////////////////////////////////////////////////////////// 



///////////////////////////////////////////////////////////////////////////////// 
//// MAIN LOOP 
///////////////////////////////////////////////////////////////////////////////// 
int main(void) 
{ 
    // Initialize the controller. 
    init(); 

    // Endless main loop. 
    while(1) 
    { 
     // 3-second delay in before starting, for ease in copying... 
     for (int n = 0; n < 3; n++) _delay_ms(1000); 

     // call central transmit routine 
     xmit_callsign(); 

     // insert a hard delay in between transmissions, for now 
     for (int n = 0; n < 3; n++) _delay_ms(1000); 
    } 
    // required but unreachable 
    return 0; 
}