2017-08-09 174 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; 
}