/**************************************************************
   RTTY DECODER (with 16seg LEDs) v1.0 2015.06.10
   5BIT-BAUDOT-CODE, 45.45BAUD
/**************************************************************/

#include <TimerOne.h>
#include <FlexiTimer2.h>

boolean  dsp;
int      i;
byte     ti;
uint8_t  baudot;

//--                  -a,b,c,d,e,f,g,h,k,m,n,p,r,s,t,u,v-
const byte font_A[] = {0,0,1,1,0,0,0,0,0,0,1,1,0,0,1,0,0};
const byte font_B[] = {1,1,1,1,1,1,0,0,0,1,0,1,0,1,0,0,0};
const byte font_C[] = {1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0};
const byte font_D[] = {1,1,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0};
const byte font_E[] = {1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,0};
const byte font_F[] = {1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0};
const byte font_G[] = {1,1,0,1,1,1,1,1,0,0,0,1,0,0,0,0,0};
const byte font_H[] = {0,0,1,1,0,0,1,1,0,0,0,1,0,0,0,1,0};
const byte font_I[] = {1,1,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0};
const byte font_J[] = {0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0};
const byte font_K[] = {0,0,0,0,0,0,1,1,0,0,1,0,1,0,0,1,0};
const byte font_L[] = {0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0};
const byte font_M[] = {0,0,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0};
const byte font_N[] = {0,0,1,1,0,0,1,1,1,0,0,0,1,0,0,0,0};
const byte font_O[] = {1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0};
const byte font_P[] = {1,1,1,0,0,0,1,1,0,0,0,1,0,0,0,1,0};
const byte font_Q[] = {1,1,1,1,1,1,1,1,0,0,0,0,1,0,0,0,0};
const byte font_R[] = {1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,0};
const byte font_S[] = {1,1,0,1,1,1,0,0,1,0,0,1,0,0,0,0,0};
const byte font_T[] = {1,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0};
const byte font_U[] = {0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0};
const byte font_V[] = {0,0,0,0,0,0,1,1,0,0,1,0,0,0,1,0,0};
const byte font_W[] = {0,0,1,1,0,0,1,1,0,0,0,0,1,0,1,0,0};
const byte font_X[] = {0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0};
const byte font_Y[] = {0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0};
const byte font_Z[] = {1,1,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0};
//--                  -a,b,c,d,e,f,g,h,k,m,n,p,r,s,t,u,v-
const byte font_0[] = {1,1,1,1,1,1,1,1,0,0,1,0,0,0,1,0,0};
const byte font_1[] = {0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0};
const byte font_2[] = {1,1,1,0,1,1,1,0,0,0,0,1,0,0,0,1,0};
const byte font_3[] = {1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0};
const byte font_4[] = {0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,1,0};
const byte font_5[] = {1,1,0,1,1,1,0,1,0,0,0,1,0,0,0,1,0};
const byte font_6[] = {1,1,0,1,1,1,1,1,0,0,0,1,0,0,0,1,0};
const byte font_7[] = {1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0};
const byte font_8[] = {1,1,1,1,1,1,1,1,0,0,0,1,0,0,0,1,0};
const byte font_9[] = {1,1,1,1,1,1,0,1,0,0,0,1,0,0,0,1,0};
//--                    -a,b,c,d,e,f,g,h,k,m,n,p,r,s,t,u,v-
const byte font_Min[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0};
const byte font_Slu[] = {0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0};
const byte font_Per[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
const byte font_Que[] = {1,1,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1};
const byte font_Col[] = {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0};

byte  dgBuf7[18];
byte  dgBuf6[18];
byte  dgBuf5[18];
byte  dgBuf4[18];
byte  dgBuf3[18];
byte  dgBuf2[18];
byte  dgBuf1[18];

void timer1_interrupt(void)
{
    volatile static byte dg = 14;
    
    switch(dg)
    {
        case 14:
            digitalWrite(20, 1);
            for(i=22; i<39; i++)
            {
                digitalWrite(i, dgBuf7[i - 22]);
            }
            digitalWrite(14, 0);
            break;
            
        case 15:
            digitalWrite(14, 1);
            for(i=22; i<39; i++)
            {
                digitalWrite(i, dgBuf6[i - 22]);
            }
            digitalWrite(15, 0);
            break;
            
        case 16:
            digitalWrite(15, 1);
            for(i=22; i<39; i++)
            {
                digitalWrite(i, dgBuf5[i - 22]);
            }
            digitalWrite(16, 0);
            break;
            
        case 17:
            digitalWrite(16, 1);
            for(i=22; i<39; i++)
            {
                digitalWrite(i, dgBuf4[i - 22]);
            }
            digitalWrite(17, 0);
            break;
            
        case 18:
            digitalWrite(17, 1);
            for(i=22; i<39; i++)
            {
                digitalWrite(i, dgBuf3[i - 22]);
            }
            digitalWrite(18, 0);
            break;
            
        case 19:
            digitalWrite(18, 1);
            for(i=22; i<39; i++)
            {
                digitalWrite(i, dgBuf2[i - 22]);
            }
            digitalWrite(19, 0);
            break;
            
        case 20:
            digitalWrite(19, 1);
            for(i=22; i<39; i++)
            {
                digitalWrite(i, dgBuf1[i - 22]);
            }
            digitalWrite(20, 0);
            break;
    }
    
    dg++;
    if(dg == 21)
    {
        dg = 14;
    }
}

void timer2_interrupt(void)
{
        static byte rSq;
        
        ti++;
        if(rSq == 0 && digitalRead(53) == 0)
        {
                rSq = 1;
                ti = 0;
        }
        if(rSq == 1 && ti == 10)
        {
                if(digitalRead(53) == 0)
                {
                        rSq = 2;
                        ti = 0;
                }
                else
                {
                        rSq = 0;
                }
        }
        if(rSq == 2 && ti == 22)
        {
                bitWrite(baudot, 0, digitalRead(53));
        }
        if(rSq == 2 && ti == 44)
        {
                bitWrite(baudot, 1, digitalRead(53));
        }
        if(rSq == 2 && ti == 66)
        {
                bitWrite(baudot, 2, digitalRead(53));
        }
        if(rSq == 2 && ti == 88)
        {
                bitWrite(baudot, 3, digitalRead(53));
        }
        if(rSq == 2 && ti == 110)
        {
                bitWrite(baudot, 4, digitalRead(53));
                dsp = 1;
        }
        if(rSq == 2 && ti == 135)
        {
                rSq = 0;
        }
}

void setup()
{  
        Timer1.initialize();
        Timer1.attachInterrupt(timer1_interrupt, 2300);
        
        FlexiTimer2::set(1, timer2_interrupt);
        FlexiTimer2::start();
      
        for(i=14; i<21; i++)//14-20,7digit
        {
             pinMode(i, OUTPUT);
        }
        for(i=22; i<39; i++)//22-38,17segment
        {
             pinMode(i, OUTPUT);
        }
      
        for(i=14; i<21; i++)//all OFF at first
        {
             digitalWrite(i, 1);
        }
        for(i=22; i<39; i++)//all OFF at first
        {
             digitalWrite(i, 0);
        }
}

void led_Print(char ch)
{
        if(ch >= 97 && ch <= 122) //CONVERT LOWER CASE TO UPPER CASE
        {
            ch = ch - 32; 
        }
        for(i=0; i<18; i++)
        {
            dgBuf7[i] = dgBuf6[i];
        }
        for(i=0; i<18; i++)
        {
            dgBuf6[i] = dgBuf5[i];
        }
        for(i=0; i<18; i++)
        {
            dgBuf5[i] = dgBuf4[i];
        }
        for(i=0; i<18; i++)
        {
            dgBuf4[i] = dgBuf3[i];
        }
        for(i=0; i<18; i++)
        {
            dgBuf3[i] = dgBuf2[i];
        }
        for(i=0; i<18; i++)
        {
            dgBuf2[i] = dgBuf1[i];
        }
        
        switch(ch)
        {
            case 'A':
                for(i=0; i<18; i++){dgBuf1[i] = font_A[i];}
                break;
                
            case 'B':
                for(i=0; i<18; i++){dgBuf1[i] = font_B[i];}
                break;
                
            case 'C':
                for(i=0; i<18; i++){dgBuf1[i] = font_C[i];}
                break;
                
            case 'D':
                for(i=0; i<18; i++){dgBuf1[i] = font_D[i];}
                break;
                
            case 'E':
                for(i=0; i<18; i++){dgBuf1[i] = font_E[i];}
                break;
                
            case 'F':
                for(i=0; i<18; i++){dgBuf1[i] = font_F[i];}
                break;
                
            case 'G':
                for(i=0; i<18; i++){dgBuf1[i] = font_G[i];}
                break;
                
            case 'H':
                for(i=0; i<18; i++){dgBuf1[i] = font_H[i];}
                break;
                
            case 'I':
                for(i=0; i<18; i++){dgBuf1[i] = font_I[i];}
                break;
                
            case 'J':
                for(i=0; i<18; i++){dgBuf1[i] = font_J[i];}
                break;
                
            case 'K':
                for(i=0; i<18; i++){dgBuf1[i] = font_K[i];}
                break;
                
            case 'L':
                for(i=0; i<18; i++){dgBuf1[i] = font_L[i];}
                break;
                
            case 'M':
                for(i=0; i<18; i++){dgBuf1[i] = font_M[i];}
                break;
                
            case 'N':
                for(i=0; i<18; i++){dgBuf1[i] = font_N[i];}
                break;
                
            case 'O':
                for(i=0; i<18; i++){dgBuf1[i] = font_O[i];}
                break;
                
            case 'P':
                for(i=0; i<18; i++){dgBuf1[i] = font_P[i];}
                break;
                
            case 'Q':
                for(i=0; i<18; i++){dgBuf1[i] = font_Q[i];}
                break;
                
            case 'R':
                for(i=0; i<18; i++){dgBuf1[i] = font_R[i];}
                break;
                
            case 'S':
                for(i=0; i<18; i++){dgBuf1[i] = font_S[i];}
                break;
                
            case 'T':
                for(i=0; i<18; i++){dgBuf1[i] = font_T[i];}
                break;
                
            case 'U':
                for(i=0; i<18; i++){dgBuf1[i] = font_U[i];}
                break;
                
            case 'V':
                for(i=0; i<18; i++){dgBuf1[i] = font_V[i];}
                break;
                
            case 'W':
                for(i=0; i<18; i++){dgBuf1[i] = font_W[i];}
                break;
                
            case 'X':
                for(i=0; i<18; i++){dgBuf1[i] = font_X[i];}
                break;
                
            case 'Y':
                for(i=0; i<18; i++){dgBuf1[i] = font_Y[i];}
                break;
                
            case 'Z':
                for(i=0; i<18; i++){dgBuf1[i] = font_Z[i];}
                break;
                
            case '0':
                for(i=0; i<18; i++){dgBuf1[i] = font_0[i];}
                break;
                
            case '1':
                for(i=0; i<18; i++){dgBuf1[i] = font_1[i];}
                break;
                
            case '2':
                for(i=0; i<18; i++){dgBuf1[i] = font_2[i];}
                break;
                
            case '3':
                for(i=0; i<18; i++){dgBuf1[i] = font_3[i];}
                break;
                
            case '4':
                for(i=0; i<18; i++){dgBuf1[i] = font_4[i];}
                break;
                
            case '5':
                for(i=0; i<18; i++){dgBuf1[i] = font_5[i];}
                break;
                
            case '6':
                for(i=0; i<18; i++){dgBuf1[i] = font_6[i];}
                break;
                
            case '7':
                for(i=0; i<18; i++){dgBuf1[i] = font_7[i];}
                break;
                
            case '8':
                for(i=0; i<18; i++){dgBuf1[i] = font_8[i];}
                break;
                
            case '9':
                for(i=0; i<18; i++){dgBuf1[i] = font_9[i];}
                break;
                
            case '-':
                for(i=0; i<18; i++){dgBuf1[i] = font_Min[i];}
                break;
                
            case '.':
                for(i=0; i<18; i++){dgBuf1[i] = font_Per[i];}
                break;
                
            case '/':
                for(i=0; i<18; i++){dgBuf1[i] = font_Slu[i];}
                break;
                
            case '?':
                for(i=0; i<18; i++){dgBuf1[i] = font_Que[i];}
                break;
                
            case ':':
                for(i=0; i<18; i++){dgBuf1[i] = font_Col[i];}
                break;
                
            default:
                for(i=0; i<18; i++){dgBuf1[i] = 0;}
        }
}

void loop()
{
        static boolean fig;
        static char    ch;
         
        if(dsp == 1)
        {
                ch = '\0';
                     if(baudot == B11111){fig = 0; } //LETTERS
                else if(baudot == B11011){fig = 1; } //FIGURES            
                else if(baudot == B01000){         } //CR
                else if(baudot == B00010){ch = ' ';} //LF
                else if(baudot == B00100){ch = ' ';} //SPACE
                if(fig == 0)
                {
                             if(baudot == B00011){ch = 'A';}
                        else if(baudot == B11001){ch = 'B';}
                        else if(baudot == B01110){ch = 'C';}
                        else if(baudot == B01001){ch = 'D';}
                        else if(baudot == B00001){ch = 'E';}
                        else if(baudot == B01101){ch = 'F';}
                        else if(baudot == B11010){ch = 'G';}
                        else if(baudot == B10100){ch = 'H';}
                        else if(baudot == B00110){ch = 'I';}
                        else if(baudot == B01011){ch = 'J';}
                        else if(baudot == B01111){ch = 'K';}
                        else if(baudot == B10010){ch = 'L';}
                        else if(baudot == B11100){ch = 'M';}
                        else if(baudot == B01100){ch = 'N';}
                        else if(baudot == B11000){ch = 'O';}
                        else if(baudot == B10110){ch = 'P';}
                        else if(baudot == B10111){ch = 'Q';}
                        else if(baudot == B01010){ch = 'R';}
                        else if(baudot == B00101){ch = 'S';}
                        else if(baudot == B10000){ch = 'T';}
                        else if(baudot == B00111){ch = 'U';}
                        else if(baudot == B11110){ch = 'V';}
                        else if(baudot == B10011){ch = 'W';}
                        else if(baudot == B11101){ch = 'X';}
                        else if(baudot == B10101){ch = 'Y';}
                        else if(baudot == B10001){ch = 'Z';}
                }
                if(fig == 1)
                {
                             if(baudot == B00011){ch = '-';}
                        else if(baudot == B11001){ch = '?';}
                        else if(baudot == B01110){ch = ':';}
                        else if(baudot == B01001){         }
                        else if(baudot == B00001){ch = '3';}
                        else if(baudot == B01101){         }
                        else if(baudot == B11010){         }
                        else if(baudot == B10100){         }
                        else if(baudot == B00110){ch = '8';}
                        else if(baudot == B01011){         }
                        else if(baudot == B01111){ch = '(';}
                        else if(baudot == B10010){ch = ')';}
                        else if(baudot == B11100){ch = '.';}
                        else if(baudot == B01100){ch = ',';}
                        else if(baudot == B11000){ch = '9';}
                        else if(baudot == B10110){ch = '0';}
                        else if(baudot == B10111){ch = '1';}
                        else if(baudot == B01010){ch = '4';}
                        else if(baudot == B00101){         }
                        else if(baudot == B10000){ch = '5';}
                        else if(baudot == B00111){ch = '7';}
                        else if(baudot == B11110){         }
                        else if(baudot == B10011){ch = '2';}
                        else if(baudot == B11101){ch = '/';}
                        else if(baudot == B10101){ch = '6';}
                        else if(baudot == B10001){         }
                }
                if(ch != '\0')
                {
                        led_Print(ch);
                }
                dsp = 0;
        }
        delay(2);
}