/********************************************************
  JI3BNB SSTV ENCODER
  Robot B/W8 Format, TEXT MESSAGE / JPEG CAMERA
  2018.07.29 v2.0
  ARDUINO "DUE" + ETHERNET SHIELD R3 + AD9850 DDS
  ETHERNET SHIELD ACTS JUST AS A "SD CARD SHIELD"
  --- THIS CODE IS IN THE PUBLIC DOMAIN --- 
  
  JPEG DECODE SECTION IS BASED ON MAKOTO KURAUCHI'S WORK
  https://github.com/MakotoKurauchi/JPEGDecoder
/********************************************************/

#include <arduino.h>
#include <SPI.h>
#include <SD.h>
#include <DueTimer.h>
#include "JPEGDecoder.h"

File myFile;
#define chipSelect 4

#define  CLK   6
#define  FQ    7
#define  DATA  8
#define  RST   9

volatile long  oFrq = 7171000; // ***** set RF OUTPUT FREQUENCY in Hz *****
volatile byte  mode;
volatile byte  sSq;
volatile int   line;
volatile int   ti;

const boolean vox = 1; // ***** USE VOX TONE OR NOT *****

const boolean aRf = 0; // ***** DDS VFO OUTPUT MODE *****
//AF: 0
//RF: 1

char line00[10] = "CQCQ SSTV"; // ***** TEXT MESSAGE 9x3 *****
char line01[10] = "DE JI3BNB";
char line02[10] = "GL PM74SS";

//FONTS
const uint8_t fonts[43][11] = {
        {0x00, 0x18, 0x24, 0x62, 0x62, 0x62, 0x7E, 0x62, 0x62, 0x62, 0x00}, //00: A
        {0x00, 0x7C, 0x32, 0x32, 0x32, 0x3C, 0x32, 0x32, 0x32, 0x7C, 0x00}, //01: B
        {0x00, 0x3C, 0x62, 0x62, 0x60, 0x60, 0x60, 0x62, 0x62, 0x3C, 0x00}, //02: C
        {0x00, 0x7C, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x7C, 0x00}, //03: D
        {0x00, 0x7E, 0x60, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x60, 0x7E, 0x00}, //04: E
        {0x00, 0x7E, 0x60, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x60, 0x60, 0x00}, //05: F
        {0x00, 0x3C, 0x62, 0x62, 0x60, 0x60, 0x66, 0x62, 0x62, 0x3C, 0x00}, //06: G
        {0x00, 0x62, 0x62, 0x62, 0x62, 0x7E, 0x62, 0x62, 0x62, 0x62, 0x00}, //07: H
        {0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00}, //08: I
        {0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x4C, 0x4C, 0x4C, 0x38, 0x00}, //09: J
        {0x00, 0x62, 0x64, 0x68, 0x70, 0x68, 0x64, 0x62, 0x62, 0x62, 0x00}, //10: K
        {0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7E, 0x00}, //11: L
        {0x00, 0x42, 0x62, 0x76, 0x6A, 0x62, 0x62, 0x62, 0x62, 0x62, 0x00}, //12: M
        {0x00, 0x42, 0x62, 0x72, 0x6A, 0x66, 0x62, 0x62, 0x62, 0x62, 0x00}, //13: N
        {0x00, 0x3C, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x3C, 0x00}, //14: O
        {0x00, 0x7C, 0x62, 0x62, 0x62, 0x7C, 0x60, 0x60, 0x60, 0x60, 0x00}, //15: P
        {0x00, 0x3C, 0x62, 0x62, 0x62, 0x62, 0x62, 0x6A, 0x6A, 0x3C, 0x08}, //16: Q
        {0x00, 0x7C, 0x62, 0x62, 0x62, 0x7C, 0x68, 0x64, 0x62, 0x62, 0x00}, //17: R
        {0x00, 0x3C, 0x62, 0x60, 0x60, 0x3C, 0x06, 0x06, 0x46, 0x3C, 0x00}, //18: S
        {0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00}, //19: T
        {0x00, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x3C, 0x00}, //20: U
        {0x00, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x22, 0x14, 0x08, 0x00}, //21: V
        {0x00, 0x62, 0x62, 0x62, 0x62, 0x62, 0x6A, 0x76, 0x62, 0x42, 0x00}, //22: W
        {0x00, 0x42, 0x62, 0x74, 0x38, 0x1C, 0x2E, 0x46, 0x42, 0x42, 0x00}, //23: X
        {0x00, 0x42, 0x62, 0x74, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00}, //24: Y
        {0x00, 0x7E, 0x06, 0x0E, 0x0C, 0x18, 0x30, 0x70, 0x60, 0x7E, 0x00}, //25: Z
        {0x00, 0x3C, 0x62, 0x62, 0x66, 0x6A, 0x72, 0x62, 0x62, 0x3C, 0x00}, //26: 0
        {0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00}, //27: 1
        {0x00, 0x3C, 0x46, 0x06, 0x06, 0x1C, 0x20, 0x60, 0x60, 0x7E, 0x00}, //28: 2
        {0x00, 0x3C, 0x46, 0x06, 0x06, 0x1C, 0x06, 0x06, 0x46, 0x3C, 0x00}, //29: 3
        {0x00, 0x0C, 0x1C, 0x2C, 0x4C, 0x4C, 0x7E, 0x0C, 0x0C, 0x0C, 0x00}, //30: 4
        {0x00, 0x7E, 0x60, 0x60, 0x60, 0x7C, 0x06, 0x06, 0x46, 0x3C, 0x00}, //31: 5
        {0x00, 0x3C, 0x62, 0x60, 0x60, 0x7C, 0x62, 0x62, 0x62, 0x3C, 0x00}, //32: 6
        {0x00, 0x7E, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00}, //33: 7
        {0x00, 0x3C, 0x62, 0x62, 0x62, 0x3C, 0x62, 0x62, 0x62, 0x3C, 0x00}, //34: 8
        {0x00, 0x3C, 0x46, 0x46, 0x46, 0x3E, 0x06, 0x06, 0x46, 0x3C, 0x00}, //35: 9
        {0x00, 0x00, 0x02, 0x06, 0x0E, 0x1C, 0x38, 0x70, 0x60, 0x40, 0x00}, //36: /
        {0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00}, //37: -
        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00}, //38: .
        {0x00, 0x3C, 0x46, 0x06, 0x06, 0x0C, 0x10, 0x00, 0x30, 0x30, 0x00}, //39: ?
        {0x00, 0x18, 0x18, 0x18, 0x18, 0x10, 0x10, 0x00, 0x18, 0x18, 0x00}, //40: !
        {0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00}, //41: :
        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}  //42: space
};

uint8_t frameBuf[19200]; //160*120

void shortPulse (char PIN)
{
        digitalWrite(PIN, 1);
        digitalWrite(PIN, 0);
}

void setFreq(double freq)
{
        //--calculate
        int32_t d_Phase = freq * pow(2, 32) / 125000000;
        //--send first 32bit
        for (int i=0; i<32; i++, d_Phase>>=1)
        {
                if(d_Phase & 1 == 1)
                {
                        digitalWrite(DATA, HIGH); //--data
                }
                else
                {
                        digitalWrite(DATA, LOW); //--data
                }
                shortPulse(CLK);
        }
        //--send rest 8bit
        digitalWrite(DATA, LOW); //--data
        for (int i=0; i<8; i++)
        {
                shortPulse(CLK);
        }
        //--finish
        shortPulse(FQ);
}

void setup()
{
        char ch;
        
        Serial.begin(9600);
        Serial1.begin(38400); //Camera Serial
        delay(100);
        while(Serial.available())
        {
                ch = Serial.read(); //flush
        }
        while(Serial1.available())
        {
                ch = Serial1.read(); //flush
        }
        Serial.println("SERIAL READY");
        
        pinMode(10, OUTPUT);
        pinMode(31, OUTPUT); //ERROR LAMP
        pinMode(33, OUTPUT); //SHOT LAMP
        digitalWrite(31, LOW);
        digitalWrite(33, LOW);
        
        if (!SD.begin(chipSelect))
        {
                Serial.println("ERROR: INSERT SD CARD AND RESTART");
                digitalWrite(31, HIGH);
                return ;
        }
        Serial.println("SD CARD INITIALIZED");
        Serial.println();
        
        pinMode(47, INPUT);
        pinMode(49, INPUT);
        digitalWrite(47, 1); //INTERNAL PULL UP
        digitalWrite(49, 1); //INTERNAL PULL UP
        
        pinMode(CLK, OUTPUT);
        pinMode(FQ, OUTPUT);
        pinMode(DATA, OUTPUT);
        pinMode(RST, OUTPUT);
        //--dds reset
        shortPulse(RST);
        shortPulse(CLK);
        //--change mode
        shortPulse(FQ);
        
        //--cam reset
        Serial1.print((char)0x56);
        Serial1.print((char)0x00);
        Serial1.print((char)0x26);
        Serial1.print((char)0x00);
        delay(1900);
        
        while(!Serial1.available()){ }
        while(Serial1.available())
        {
                Serial.print(Serial1.read(), HEX);
                Serial.print(" ");
        }
        Serial.println();
        
        //--cam setSize
        Serial1.print((char)0x56);
        Serial1.print((char)0x00);
        Serial1.print((char)0x54);
        Serial1.print((char)0x01);
        Serial1.print((char)0x22); //160*120
        delay(100);
        
        while(!Serial1.available()){ }
        while(Serial1.available())
        {
                Serial.print(Serial1.read(), HEX);
                Serial.print(" ");
        }
        Serial.println();
        
        Serial.println("JPEG CAMERA INITIALIZED");
        Serial.println();
        
        Timer1.attachInterrupt(timer1_interrupt).start(352); // ***** 354(uS/px) +/- SLANT ADJUST *****
        delay(100);
}

void timer1_interrupt(void)
{
        int p;
        
        if(sSq == 3)
        {
                if(mode == 1)
                {
                        if(ti < 160)
                        {
                                p = (160 * line) + ti;
                                
                                if(aRf == 0)
                                {
                                        setFreq(1500 + 3.13 * frameBuf[p]);
                                }
                                else
                                {
                                        setFreq(oFrq - (1500 + 3.13 * frameBuf[p]));
                                }
                        }
                        else if(ti == 160)
                        {
                                line++;
                                sSq = 2;
                        }
                        if(line == 120)
                        {
                                sSq = 0;
                        }
                        ti++;
                }
                else if(mode == 0)
                {
                        if(line >= 40 && line <= 72)
                        {
                                if(ti < 160)
                                {
                                        p = 160 * (line - 40) + ti;
                                        if(aRf == 0)
                                        {
                                                if(frameBuf[p])
                                                {
                                                        setFreq(2300);
                                                }
                                                else
                                                {
                                                        setFreq(1500);
                                                }
                                        }
                                        else
                                        {
                                                if(frameBuf[p])
                                                {
                                                        setFreq(oFrq - 2300);
                                                }
                                                else
                                                {
                                                        setFreq(oFrq - 1500);
                                                }
                                        }
                                }
                                else if(ti == 160)
                                {
                                        line++;
                                        sSq = 2;
                                }
                        }
                        else
                        {
                                if(aRf == 0)
                                {
                                        switch(ti)
                                        {
                                                case 0:
                                                        setFreq(1500);
                                                        break;
                                                case 40:
                                                        setFreq(1767);
                                                        break;
                                                case 80:
                                                        setFreq(2033);
                                                        break;
                                                case 120:
                                                        setFreq(2300);
                                                        break;
                                                case 160:
                                                        line++;
                                                        if(line == 120)
                                                        {
                                                                sSq = 0;
                                                        }
                                                        else
                                                        {
                                                                sSq =2;
                                                        }
                                                        break;
                                        }
                                }
                                else
                                {
                                        switch(ti)
                                        {
                                                case 0:
                                                        setFreq(oFrq - 1500);
                                                        break;
                                                case 40:
                                                        setFreq(oFrq - 1767);
                                                        break;
                                                case 80:
                                                        setFreq(oFrq - 2033);
                                                        break;
                                                case 120:
                                                        setFreq(oFrq - 2300);
                                                        break;
                                                case 160:
                                                        line++;
                                                        if(line == 120)
                                                        {
                                                                sSq = 0;
                                                        }
                                                        else
                                                        {
                                                                sSq =2;
                                                        }
                                                        break;
                                        }
                                }
                        }
                        ti++;
                }
        }
}

void jpegTake(void)
{
        byte start_addr_m;
        byte start_addr_l;
        boolean jpegEnd;
        int  jpegEndPos;
        int  byteCount;
        byte incomingByte;
        byte jpegArray[20001];
        boolean err;
        int  i;
        
        Serial.println();
        Serial.println("NEW FILE");
        
        //--cam takePhoto
        digitalWrite(33, HIGH);
        Serial1.print((char)0x56);
        Serial1.print((char)0x00);
        Serial1.print((char)0x36);
        Serial1.print((char)0x01);
        Serial1.print((char)0x00);
        delay(100);
        
        while(!Serial1.available()){ }
        digitalWrite(33, LOW);
        while(Serial1.available())
        {
                Serial.print(Serial1.read(), HEX);
                Serial.print(" ");
        }
        Serial.println();
        
        //--cam readSize
        Serial1.print((char)0x56);
        Serial1.print((char)0x00);
        Serial1.print((char)0x34);
        Serial1.print((char)0x01);
        Serial1.print((char)0x00);
        delay(100);
        
        while(!Serial1.available()){ }
        while(Serial1.available())
        {
                Serial.print(Serial1.read(), HEX);
                Serial.print(" ");
        }
        Serial.println();
        
        //--cam readContent
        start_addr_m = 0x00;
        start_addr_l = 0x00;
        jpegEnd = false;
        i = 0;
        
        while(!jpegEnd)
        {
                /*
                Serial.print("start_addr: ");
                Serial.print(start_addr_m, HEX);
                Serial.print(" ");
                Serial.print(start_addr_l, HEX);
                Serial.println();
                delay(10);
                */
                Serial1.print((char)0x56);
                Serial1.print((char)0x00);
                Serial1.print((char)0x32);
                Serial1.print((char)0x0C);
                Serial1.print((char)0x00);
                Serial1.print((char)0x0A);
                Serial1.print((char)0x00);
                Serial1.print((char)0x00);
                
                Serial1.print((char)start_addr_m);  //MM
                Serial1.print((char)start_addr_l);  //MM
                
                Serial1.print((char)0x00);
                Serial1.print((char)0x00);
                Serial1.print((char)0x00);  //KK
                Serial1.print((char)0x20);  //KK (DEC:32)
                Serial1.print((char)0x00);  //XX
                Serial1.print((char)0x0A);  //XX
                
                while(!Serial1.available()){ }
                delay(22); //10ms at least
                
                byteCount = 0;
                while(Serial1.available())
                {
                        incomingByte = Serial1.read();
                        /*
                        Serial.print(incomingByte, HEX);
                        Serial.print(" ");
                        */
                        if(byteCount >=5 && byteCount <=36)
                        {
                                jpegArray[i] = incomingByte;
                                if(jpegArray[i - 1] == 0xFF && jpegArray[i] == 0xD9)
                                {
                                        /*
                                        Serial.println("CAUGHT FFD9!");
                                        */
                                        jpegEndPos = i;
                                        jpegEnd = true;
                                }
                                i++;
                        }
                        byteCount++;
                }
                /*
                Serial.println();
                */
                if(start_addr_l == 0xE0)
                {
                        start_addr_l = 0x00;
                        start_addr_m += 0x01;
                }
                else
                {
                        start_addr_l += 0x20; //DEC:32
                }
        }
        
        //--cam stop
        Serial1.print((char)0x56);
        Serial1.print((char)0x00);
        Serial1.print((char)0x36);
        Serial1.print((char)0x01);
        Serial1.print((char)0x03);
        delay(100);
        
        while(!Serial1.available()){ }
        while(Serial1.available())
        {
                Serial.print(Serial1.read(), HEX);
                Serial.print(" ");
        }
        Serial.println();
        
        //--jpeg fileSave
        err = false;
        myFile = SD.open("SSTV.JPG", FILE_WRITE | O_TRUNC);
        if(myFile)
        {
                for(i = 0; i <= jpegEndPos; i++)
                {
                        myFile.write(jpegArray[i]);
                }
        }
        else
        {
                Serial.println("CAN'T OPEN FILE");
                err = true;
        }
        myFile.close();
        
        if(err == true)
        {
                digitalWrite(31, HIGH);
                while(1);
        }
        else
        {
                Serial.println("JPEG FILE SAVED");
                Serial.println();
        }
}

void jpegDecode(void)
{
        char str[100];
        char filename[] = "SSTV.JPG";
        uint8 *pImg;
        int x,y,bx,by;
        
        float   pxGr;
        uint8_t pxGr_;
        int i;
        
        // Decoding start
        JpegDec.decode(filename,0);
        
        // Image Information
        Serial.print("Width     :");
        Serial.println(JpegDec.width);
        Serial.print("Height    :");
        Serial.println(JpegDec.height);
        Serial.print("Components:");
        Serial.println(JpegDec.comps);
        Serial.print("MCU / row :");
        Serial.println(JpegDec.MCUSPerRow);
        Serial.print("MCU / col :");
        Serial.println(JpegDec.MCUSPerCol);
        Serial.print("Scan type :");
        Serial.println(JpegDec.scanType);
        Serial.print("MCU width :");
        Serial.println(JpegDec.MCUWidth);
        Serial.print("MCU height:");
        Serial.println(JpegDec.MCUHeight);
        Serial.println("");
        
        // Output CSV
        sprintf(str,"#SIZE,%d,%d",JpegDec.width,JpegDec.height);
        Serial.println(str);
        
        // Image size error
        if(JpegDec.width != 160 || JpegDec.height != 120)
        {
                digitalWrite(31, HIGH);
                Serial.println("ERROR: PICTURE SIZE SHOULD BE 160*120") ;
                while(1);
        }
        
        // Clear buffer
        for(i = 0; i < 19200; i++)
        {
                frameBuf[i] = 0xFF;
        }
        
        while(JpegDec.read())
        {
                pImg = JpegDec.pImage ;
                
                for(by=0; by < JpegDec.MCUHeight; by++)
                {
                        for(bx=0; bx < JpegDec.MCUWidth; bx++)
                        {
                                x = JpegDec.MCUx * JpegDec.MCUWidth + bx;
                                y = JpegDec.MCUy * JpegDec.MCUHeight + by;
                                
                                if(x < JpegDec.width && y < JpegDec.height)
                                {
                                        if(JpegDec.comps == 1) // Grayscale
                                        {
                                                //sprintf(str,"#RGB,%d,%d,%u", x, y, pImg[0]);
                                                //Serial.println(str);
                                                
                                                frameBuf[(160 * y) + x] = pImg[0];
                                        }
                                        else // RGB
                                        {
                                                //sprintf(str,"#RGB,%d,%d,%u,%u,%u", x, y, pImg[0], pImg[1], pImg[2]);
                                                //Serial.println(str);
                                                
                                                pxGr = ((pImg[0] * 0.30) + (pImg[1] * 0.59) + (pImg[2] * 0.11));
                                                pxGr_ = (uint8_t)pxGr;
                                                frameBuf[(160 * y) + x] = pxGr_;
                                        }
                                }
                                pImg += JpegDec.comps ;
                        }
                }
        }
        //for(;;);
        Serial.println("JPEG FILE DECODED");
        Serial.println();
}

void loop()
{
        int x,y,i,p;
        
        if(sSq == 0)
        {
                setFreq(2);
                while(sSq == 0)
                {
                        if(digitalRead(47) == 0) // - SEND SW -
                        {
                                sSq = 1;
                        }
                        else
                        {
                                delay(30);
                        }
                }
        }
        else if(sSq == 1)
        {
                if(digitalRead(49) == 1) // - MODE SW -
                {
                        mode = 1; //CAMERA MODE 
                        
                        jpegTake();
                        jpegDecode();
                        
                        //--Adjust Brightness
                        for(p = 0; p < 19200; p++)
                        {
                                frameBuf[p] += 0x20;
                                if(frameBuf[p] < 0x20)
                                {
                                        frameBuf[p] = 0xFF;
                                }
                        }
                }                        
                else
                {
                        mode = 0; //TEXT MODE
                        
                        for(p = 0; p < 5280; p++) //160*33
                        {
                                frameBuf[p] = 0xFF;
                        }
                        
                        for(i = 0; i < 27; i++)
                        {
                                byte fontNumber;
                                char ch;
                                
                                if(i < 9)
                                {
                                        ch = line00[i];
                                }
                                else if(i < 18)
                                {
                                        ch = line01[i - 9];
                                }
                                else
                                {
                                        ch = line02[i - 18];
                                }
                                
                                for(y = 0; y < 11; y++)
                                {
                                        for(x = 0; x < 8; x++)
                                        {
                                                if(i < 9)
                                                {
                                                        p = 8 + (160 * y) + (2 * 8 * i) + (2 * x); //Width: x2
                                                }
                                                else if(i < 18)
                                                {
                                                        p = 8 + (160 * 11) + (160 * y) + (2 * (8 * (i - 9))) + (2 * x); //Width: x2
                                                }
                                                else
                                                {
                                                        p = 8 + (160 * 22) + (160 * y) + (2 * (8 * (i - 18))) + (2 * x); //Width: x2
                                                }
                                                
                                                uint8_t mask;
                                                mask = pow(2, 7 - x);
                                                
                                                if(ch >= 65 && ch <= 90) //A to Z
                                                {
                                                        fontNumber = ch - 65;
                                                }
                                                else if(ch >= 48 && ch <= 57) //0 to 9
                                                {
                                                        fontNumber = ch - 22;
                                                }
                                                else if(ch == '/'){fontNumber = 36;}
                                                else if(ch == '-'){fontNumber = 37;}
                                                else if(ch == '.'){fontNumber = 38;}
                                                else if(ch == '?'){fontNumber = 39;}
                                                else if(ch == '!'){fontNumber = 40;}
                                                else if(ch == ':'){fontNumber = 41;}
                                                else if(ch == ' '){fontNumber = 42;}
                                                else              {fontNumber = 42;}
                                                
                                                if((fonts[fontNumber][y] & mask) != 0)
                                                {
                                                        frameBuf[p    ] = 0x00;
                                                        frameBuf[p + 1] = 0x00;
                                                }
                                        }
                                }
                        }
                }
                
                if(mode == 0)
                {
                        delay(800);
                }
                
                if(aRf == 0)
                {
                        //--VOX TONE
                        if(vox == 1)
                        {
                                setFreq(1900);
                                delay(100);
                                setFreq(1500);
                                delay(100);
                                setFreq(1900);
                                delay(100);
                                setFreq(1500);
                                delay(100);
                                setFreq(2300);
                                delay(100);
                                setFreq(1500);
                                delay(100);
                                setFreq(2300);
                                delay(100);
                                setFreq(1500);
                                delay(100);
                        }
                        
                        //--VIS CODE
                        //VIS CODE for ROBOT B/W 8S is B0000010 (DECIMAL 2)
                        setFreq(1900);
                        delay(300);
                        setFreq(1200); //BREAK
                        delay(10);
                        setFreq(1900);
                        delay(300);
                        setFreq(1200); //START BIT
                        delay(30);
                        setFreq(1300); //BIT 0 (LSB FIRST)
                        delay(30);
                        setFreq(1100); //BIT 1
                        delay(30);
                        setFreq(1300); //BIT 2, 3, 4, 5, 6
                        delay(150);
                        setFreq(1100); //EVEN PARITY
                        delay(30);
                        setFreq(1200); //STOP BIT
                        delay(30);
                }
                else
                {
                        //--VIS CODE
                        setFreq(oFrq - 1900);
                        delay(300);
                        setFreq(oFrq - 1200); //BREAK
                        delay(10);
                        setFreq(oFrq - 1900);
                        delay(300);
                        setFreq(oFrq - 1200); //START BIT
                        delay(30);
                        setFreq(oFrq - 1300); //BIT 0 (LSB FIRST)
                        delay(30);
                        setFreq(oFrq - 1100); //BIT 1
                        delay(30);
                        setFreq(oFrq - 1300); //BIT 2, 3, 4, 5, 6
                        delay(150);
                        setFreq(oFrq - 1100); //EVEN PARITY
                        delay(30);
                        setFreq(oFrq - 1200); //STOP BIT
                        delay(30);
                }
                //--VIS DONE
                line = 0;
                sSq  = 2;
        }
        else if(sSq == 2)
        {
                //--sync
                if(aRf == 0)
                {
                        setFreq(1200);
                        delayMicroseconds(10000);
                }
                else
                {
                        setFreq(oFrq - 1200);
                        delayMicroseconds(10000);
                }
                //--
                ti  = 0;
                sSq = 3;
        }
}