1: standard
2: advanced1
3: advanced2
4: semiauto
5: clear by code
6: set by code
>>5
5: clearing by code
Give code
>>1234
Cycle 1234
...
//(c) 2020 Janne Kivijakola
#define IMMO_PIN 2
#define IMMO_PIN_ACTIVE_STATE HIGH
#define PWR_PIN 3
#define PWR_PIN_ACTIVE_STATE HIGH
unsigned long DELAY_TIME = 12500; // 12.5 msec
void setup()
{
Serial.begin(115200);
Serial.print("\n\nStart\n");
pinMode(IMMO_PIN, OUTPUT);
digitalWrite(IMMO_PIN, !IMMO_PIN_ACTIVE_STATE);
pinMode(PWR_PIN, OUTPUT);
digitalWrite(PWR_PIN, !PWR_PIN_ACTIVE_STATE);
}
void loop()
{
char serialByte = 0;
Serial.println("\n1: standard");
Serial.println("2: advanced1");
Serial.println("3: advanced2");
Serial.println("4: semiauto");
Serial.println("5: clear by code");
Serial.println("6: set by code (IMMO emulator)");
Serial.print(">>");
while (serialByte < '0' || serialByte > '6')
{
if (Serial.available() > 0)
{
serialByte = Serial.read();
}
}
Serial.println(serialByte);
switch (serialByte)
{
case '1':
standard();
break;
case '2':
advanced1();
break;
case '3':
advanced2();
break;
case '4':
semiauto();
break;
case '5':
clearbycode();
break;
case '6':
setcode();
break;
}
}
void standard()
{
Serial.println("\n1: standard");
while (Serial.available() > 0)
Serial.read();
process(16, 2, 0, 0, 0);
}
void advanced1()
{
Serial.println("2: advanced1");
while (Serial.available() > 0)
Serial.read();
process(16, 5, 0, 0, 0);
}
void advanced2()
{
Serial.println("3: advanced2");
while (Serial.available() > 0)
Serial.read();
process(48, 6, 0, 0, 0);
}
void semiauto()
{
Serial.println("4: semiauto");
while (Serial.available() > 0)
Serial.read();
process(16, 7, 1, 0, 0);
}
void clearbycode()
{
int code = 472;
Serial.println("5: clearing by code");
code = readInteger();
process(48, 2, 0, code, 0);
}
void setcode()
{
int code = 0;
Serial.println("5: setting code");
while(code<=0)
code = readInteger();
process(48, 2, 0, code, 1);
}
int readInteger()
{
char serialByte = 0;
int receivedBytes = 0;
char serbuffer[10] ={};
Serial.print("Give code\n>>");
while (Serial.available() > 0)
Serial.read();
while (1)
{
if (Serial.available() > 0)
{
serialByte = Serial.read();
if((serialByte >= '0' && serialByte <= '9')||receivedBytes > 4)
{
serbuffer[receivedBytes++] = serialByte;
}
else
break;
}
}
Serial.println(serbuffer);
return atoi(serbuffer);
}
void process(int resetStateBits, int rounds, int mode, int myOwnCode, int setCode)
{
unsigned long delayStart = 0;
int counter = 1;
int bitsRemaining = 0;
int currentRound = 0;
unsigned long pipeline = 0;
int resetStateRemaining = 0;
int dataWidth = 22;
if (mode == 1)
{
dataWidth = 9;
}
if(myOwnCode!=0)
{
counter = myOwnCode;
resetStateRemaining = resetStateBits;
}
delayStart = micros();
while (1)
{
int immoPinState = 0;
if (((micros() - delayStart) >= DELAY_TIME))
{
delayStart += DELAY_TIME;
if (!bitsRemaining)
{
if (Serial.available() > 0)
return;
if (!mode)
bitsRemaining = 32;
else
bitsRemaining = 18;
if (currentRound >= rounds && myOwnCode == 0)
{
counter++;
currentRound = 0;
resetStateRemaining = resetStateBits;
}
unsigned long A=1;
if(setCode==1)
{
A=0;
}
if (!mode)
/*
* IGN __-------------------------------------------------___-------------------------------------------------__
* IMMO__SSS_AIIIBJJJJCKKKKDLLLLE_SSS_AIIIBJJJJCKKKKDLLLLE___SSS_AIIIBJJJJCKKKKDLLLLE_SSS_AIIIBJJJJCKKKKDLLLLE
* round1 round2 round1 round2
* counter1 counter2
* A: Clear code bit
* B,C,D,E: Sync bits
* I,J,K,L: Data bits
* S:
*/
pipeline = A << 19 //A
| ((counter & 0x7000UL) << 4) //III
| (1UL & ~(0x1UL & (counter >> 12))) << 15 //B
| ((counter & 0x0f00) << 3) //JJJJ
| (1 & ~(0x1 & (counter >> 8))) << 10 //C
| ((counter & 0x00f0) << 2) //KKKK
| (1 & ~(0x1 & (counter >> 4))) << 5 //D
| ((counter & 0x000f) << 1) //LLLL
| (1 & ~(0x1 & (counter >> 0))) << 0; //E
else
/*
* IGN __---------------------------------------...___---------------------------------------...
* IMMO__SSS_IIIIIIII_SSS_IIIIIIII_SSS_IIIIIIII_...___SSS_IIIIIIII_SSS_IIIIIIII_SSS_IIIIIIII_...
* round1 round2 round3 round1 round2 round3
* counter1 counter2
*/
pipeline = ((counter + 1) & 0x00ffUL) << 13;//IIIIIIII
if (currentRound == 0)
{
Serial.print("Cycle ");
Serial.print(counter);
Serial.print(" / ");
if (mode == 0)
{
Serial.print("6562");
}
else
{
int code = (counter & 3) + 1
+ 10 * (((counter >> 2) & 3) + 1)
+ 100 * (((counter >> 4) & 3) + 1)
+ 1000 * (((counter >> 6) & 3) + 1);
Serial.print("255");
Serial.print(" code: ");
Serial.print(code);
}
Serial.print("\n");
if ((counter == 6562 && mode == 0)
|| (counter == 255 && mode == 1))
{
Serial.print("DONE\n");
return;
}
}
currentRound++;
}
if (resetStateRemaining)
{
digitalWrite(PWR_PIN, !PWR_PIN_ACTIVE_STATE);
resetStateRemaining--;
}
else
{
//start bits
if (bitsRemaining > dataWidth)
immoPinState = 1;
//data streaming
else
{
immoPinState = (pipeline & 0x100000UL) >> 20;
pipeline <<= 1;
}
if (immoPinState)
{
digitalWrite(IMMO_PIN, IMMO_PIN_ACTIVE_STATE);
}
else
{
digitalWrite(IMMO_PIN, !IMMO_PIN_ACTIVE_STATE);
}
digitalWrite(PWR_PIN, PWR_PIN_ACTIVE_STATE);
bitsRemaining--;
}
}
}
}