Saturday November 25 2017

IR Toy Arduino Code

/////////////////////////////////////////////////////////////////////////////////
// *** ALL MY Code is 100% free of cost and liability *** 
boolean EnableINT_Disable = false;  // Will poll serial and not use INT, so don't need ISR dissable
boolean BurstPortB = true;
int IRledPin = 8;
boolean Xmit_S107 = false;
boolean Xmit_Inch = false;
// FSM
int numBuff = 5;
char FSM[5] = {0,0,0,0,0};
// Heli
int Speeds[4] = {63,63,0,63};
int SpeedsInit[4] = {63,63,0,63};
char ThrustID = 127; // Note delta value must be [1,123] with +64 offset thus [-63,59]
char PitchID  = 126; // So these IDs should be fine
char YawID    = 125;
char YawAdjID = 124;
// Inch
char InchDirCmd = '0';
/////////////////////////////////////////////////////////////////////////////////
void setup() {
    if(BurstPortB) DDRB |= B1111;
    else           pinMode(IRledPin,OUTPUT);
    Serial.begin(115200);
    Serial.println("IR Emitter Turned On");
}
/////////////////////////////////////////////////////////////////////////////////
void loop() {
    pollSerial(); // By polling the Serial, we can avoid all that ISR dissabling stuff
    if(Xmit_S107) Xmit_S107Code(Speeds);
    if(Xmit_Inch) Xmit_InchCode(InchDirCmd);
}
/////////////////////////////////////////////////////////////////////////////////
void pollSerial() {
    if(Serial.available() > 0) {
        char tempc = Serial.read();
        CrunchFSM(tempc);
    }
}
/////////////////////////////////////////////////////////////////////////////////
void CrunchFSM(char newChar) {
    if(newChar != 0) {
        for(int i=numBuff-1;i>=0;i--) {
            if(i==0) FSM[i] = newChar;
            else     FSM[i] = FSM[i-1];
        }
        if((FSM[0]==FSM[1])&&(FSM[1]==FSM[2])&&(FSM[2]==FSM[3])&&(FSM[3]==FSM[4])&&(FSM[4]=='H')) {
            Xmit_S107 = !Xmit_S107;
            Serial.print("IRToy: Helicopter Constant Update Enb:");
            Serial.println(Xmit_S107?"T":"F");
        } else if((FSM[0]==FSM[1])&&(FSM[1]==FSM[2])&&(FSM[2]==FSM[3])&&(FSM[3]==FSM[4])&&(FSM[4]=='I')) {
            Xmit_Inch = !Xmit_Inch;
            Serial.print("IRToy: Inchworm Constant Update Enb:");
            Serial.println(Xmit_Inch?"T":"F");
        } else if((FSM[0]==FSM[1])&&(FSM[1]==FSM[2])&&(FSM[2]==FSM[3])&&(FSM[3]==FSM[4])&&(FSM[4]=='K')) {
                for(int i=0;i<4;i++) Speeds[i] = SpeedsInit[i];
                InchDirCmd = '0';
                Serial.println("KillEngaged");
        } else if((FSM[0]==FSM[1])&&(FSM[1]==FSM[3])&&(FSM[3]==FSM[4])&&(FSM[4]=='D')) {
            Debug(FSM[2]);
        } else {
            ProcessB5Pattern(FSM);
        }
    }
}
/////////////////////////////////////////////////////////////////////////////////
void ProcessB5Pattern(char Pattern[]) {
    // char ID;
    // Helicopter
    if((Pattern[0] == Pattern[4])&&(Pattern[0] == 'H')&&(Pattern[1] == Pattern[3])) {
        int Delta = (int)Pattern[2] - 64;
        char ID = Pattern[1];
        if(ID == YawID){
            Speeds[0] += Delta;
            if(Speeds[0] < 0)   Speeds[0] = 0;
            if(Speeds[0] > 127) Speeds[0] = 127;
        } else if(ID == PitchID) {
            Speeds[1] += Delta;
            if(Speeds[1] < 0)   Speeds[1] = 0;
            if(Speeds[1] > 127) Speeds[1] = 127;
        } else if(ID == ThrustID) {
            Speeds[2] += Delta;
            if(Speeds[2] < 0)   Speeds[2] = 0;
            if(Speeds[2] > 125) Speeds[2] = 125;
        } else if(ID == YawAdjID){
            Speeds[3] += Delta;
            if(Speeds[3] < 0)   Speeds[3] = 0;
            if(Speeds[3] > 127) Speeds[3] = 127;
        } else {
            String PrintOut = "";
            PrintOut += "  Got Invalid ID(" ;
            PrintOut += ID;
            Serial.println(PrintOut + ") for:" + Delta);
            Serial.println(" ");
        }
    // Inchworm
    } else if((Pattern[0] == Pattern[4])&&(Pattern[0] == 'I')&&(Pattern[1] == Pattern[2])&&(Pattern[2] == Pattern[3])) {
        if(Xmit_Inch) InchDirCmd = Pattern[2];   // If auto update enabled, overwrite
        else for(int i=0;i<2;i++) Xmit_InchCode(Pattern[2]);
    }
}
/////////////////////////////////////////////////////////////////////////////////
void Debug(char select) {
    if(select == 'b') {
        BurstPortB = !BurstPortB;
        Serial.print("BurstPortB:");
        Serial.println(BurstPortB?"T":"F");
    }
    Serial.println("DebugDone");
}
/////////////////////////////////////////////////////////////////////////////////
void Xmit_S107Code(int ValueArray[]) {
    uint16_t pinID = IRledPin;
    // Header
    pulseIR_38KHz(4000,pinID);
    delayMicroseconds(2000);
    // Body
    sendCharArray(ValueArray,4,300,600,300,pinID);
    // Footer
    pulseIR_38KHz(360,pinID);
    digitalWrite(pinID, LOW);
    delay(65);
}
/////////////////////////////////////////////////////////////////////////////////
void Xmit_InchCode(char Code) {
    uint16_t pinID = IRledPin;
    int CodeArray[1] = {0};
    if      (Code == 'F') CodeArray[0] = 131;
    else if (Code == 'B') CodeArray[0] = 69; // heheh
    else if (Code == 'R') CodeArray[0] = 38;
    else if (Code == 'L') CodeArray[0] = 193;
    // Header
    pulseIR_38KHz(4000,pinID); delayMicroseconds(400);
    pulseIR_38KHz(2000,pinID); delayMicroseconds(800);
    // Body
    sendCharArray(CodeArray,1,400,1400,500,pinID);
    // Footer
    pulseIR_38KHz(400,pinID); delayMicroseconds(1400);
    pulseIR_38KHz(400,pinID); delayMicroseconds(1400);
    pulseIR_38KHz(400,pinID);
    digitalWrite(pinID, LOW);
    delay(65);
}
/////////////////////////////////////////////////////////////////////////////////
void sendCharArray(int CharArray[], uint16_t size, uint16_t PulseOn, uint16_t DelayTrue, uint16_t DelayFalse, uint16_t pinID) {
    int tempc = 0;
    for(int i=0;i < size;i++) {
        tempc = CharArray[i];
        for(int j=7;j>=0;j--) {
            pulseIR_38KHz(PulseOn,pinID);
            if (((tempc>>j)%2) == 1) delayMicroseconds(DelayTrue);
            else                     delayMicroseconds(DelayFalse);
        }
    }
}
/////////////////////////////////////////////////////////////////////////////////
void pulseIR_38KHz(long microsecs, uint16_t pinID) {
    if(EnableINT_Disable) cli();  // Dissable Interrupts (like serial event)
    if(BurstPortB) {
        while (microsecs > 0) {
            // 38KHz = 26.316us -> 26us, so cut in 1/2 for IR pulse -> 13us high, 13us low
            PORTB = B1111;  // Takes ~1/2us
            delayMicroseconds(13);
            PORTB = B0000;  // Takes ~1/2us
            delayMicroseconds(12);
            microsecs -= 26;
        }
    } else {
        while (microsecs > 0) {
            // 38KHz = 26.316us -> 26us, so cut in 1/2 for IR pulse -> 13us high, 13us low
            digitalWrite(pinID, HIGH);  // Takes ~3us
            delayMicroseconds(10);
            digitalWrite(pinID, LOW);   // Takes ~3us
            delayMicroseconds(10);
            microsecs -= 26;
        }
    }
    if(EnableINT_Disable) sei();  // Enable Interupts
}
/////////////////////////////////////////////////////////////////////////////////