Snippets
Created by
Simon Johnson
last modified
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | /*
* MilesTag Gamebox V3 Simulator
*
* An IR detector/demodulator must be connected to the input RECV_PIN.
* An IR LED must be connected to the output PWM pin 3.
* A push button with pull-up resistor must be connected to the input BUTTON_PIN;
* this is the send button.
* A visible LED can be connected to STATUS_PIN to provide status.
*
* The logic is:
* On startup, retrieve the stored IR code value from the EEPROM.
* If the button is pressed, send the IR code.
* If an IR code is received, record it and save it to the EEPROM.
*
* Version 0.0.1 December, 2016
* By Simon Johnson
* http://redcrowdigital.com
*/
#include <IRremote.h>
#include <EEPROM.h>
int RECV_PIN = 5;
int BUTTON_PIN = 12;
int STATUS_PIN = 8;
IRrecv irrecv(RECV_PIN);
IRsend irsend;
decode_results results;
// Declare some globals to store our IR codes
unsigned long codesAmmo[16][2];
unsigned long codesMedic[16][2];
unsigned long codesFlag[16][2];
unsigned long codesHazard[16][2];
unsigned long codesTeamRespawn1[4][2];
unsigned long codesTeamRespawn2[4][2];
unsigned long codeRespawn[2][2];
unsigned long codeAmmo[2][2];
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
pinMode(BUTTON_PIN, INPUT);
pinMode(STATUS_PIN, OUTPUT);
// On startup, set codeValue to whatever is in the EEPROM
getCode();
setCodeArray(codesAmmo, 11665640, 9044200, 16, 256, 256);
setCodeArray(codesMedic, 11731176, 9109736, 16, 256, 256);
setCodeArray(codesFlag, 11862248, 9175272, 16, 256, 256);
setCodeArray(codesHazard, 12255464, 8782056, 16, 256, 256);
// Codes for the 3 below here seem to change.
setCodeArray(codesTeamRespawn1, 11994344, 8913128, 4, 65536, 256); // Sometimes the respawn input codes will differ by 1024.
setCodeArray(codesTeamRespawn2, 11993320, 8913128, 4, 65536, 256); // So we use 2 separate arrays for them.
setCodeArray(codeRespawn, 11927784, 8586472, 2, 1024, 0); // 2 possible inputs, 1024 apart.
setCodeArray(codeAmmo, 12321000, 8586984, 2, 1024, 0); // 2 possible inputs, 1024 apart.
}
// Globals
unsigned long codeValue = -1; // The code value if not raw
int codeLen; // The length of the code
// Initialize a 2 dimensional array of IR code pairs
void setCodeArray(unsigned long array[][2], unsigned long inputStart, unsigned long outputStart, int len, long inputInterval, int outputInterval) {
// loop over the array, setting the values
for (int i = 0; i < len; i++) {
array[i][0] = inputStart + (i * inputInterval);
array[i][1] = outputStart + (i * outputInterval);
}
}
// Stores the code for later playback
void storeCode(decode_results *results) {
int codeType = -1; // The type of code
codeType = results->decode_type;
int count = results->rawlen;
unsigned long actionCode = 0;
if (codeType == SONY) {
Serial.print("Received SONY: ");
Serial.println(results->value, HEX);
Serial.println(results->value);
Serial.println(results->bits);
actionCode = mapCode(results->value, results->bits);
Serial.print("actionCode: ");
Serial.println(actionCode);
if (actionCode != 0) {
saveCode(actionCode);
}
} else {
Serial.print("Unexpected codeType ");
Serial.print(codeType, DEC);
Serial.println("");
}
}
// Given an 'input' code, find and return its matching output code by searching our global arrays
unsigned long mapCode(long inputCode, int len) {
Serial.print("inputCode: ");
Serial.println(inputCode);
unsigned long outputCode = 0;
if (len == 24){
outputCode = searchArray(codesAmmo, inputCode, 16);
if (outputCode == 0) {
outputCode = searchArray(codesMedic, inputCode, 16);
}
if (outputCode == 0) {
outputCode = searchArray(codesFlag, inputCode, 16);
}
if (outputCode == 0) {
outputCode = searchArray(codesHazard, inputCode, 16);
}
if (outputCode == 0) {
outputCode = searchArray(codesTeamRespawn1, inputCode, 4);
}
if (outputCode == 0) {
outputCode = searchArray(codesTeamRespawn2, inputCode, 4);
}
if (outputCode == 0) {
outputCode = searchArray(codeRespawn, inputCode, 2);
}
if (outputCode == 0) {
outputCode = searchArray(codeAmmo, inputCode, 2);
}
}
Serial.print("outputCode: ");
Serial.println(outputCode);
return outputCode;
}
// Search for something in an array and return its corresponding value
unsigned long searchArray(unsigned long array[][2], unsigned long value, int len) {
for (int i = 0; i < len; i++) {
if (array[i][0] == value) {
return array[i][1];
}
}
return 0;
}
// Store code in the EEPROM
void saveCode(unsigned long code) {
int eeAddress = 0; //Location we want the data to be put.
EEPROMWritelong(eeAddress, code);
Serial.println(code);
Serial.print("Code has been written to EEPROM address: ");
Serial.println(eeAddress);
// Also update the global
codeValue = code;
}
// Retrieve a codeValue from the EEPROM
// Set the retrieved value as codeValue
void getCode() {
unsigned long code = 0; //Variable to store data read from EEPROM.
int eeAddress = 0; //EEPROM address to start reading from
//Get data from the EEPROM at position 'eeAddress'
codeValue = EEPROMReadlong(eeAddress);
Serial.print("Read code from EEPROM: ");
Serial.println(codeValue);
}
//This function will write a 4 byte (32bit) long to the eeprom at
//the specified address to address + 3.
void EEPROMWritelong(int address, long value) {
//Decomposition from a long to 4 bytes by using bitshift.
//One = Most significant -> Four = Least significant byte
byte four = (value & 0xFF);
byte three = ((value >> 8) & 0xFF);
byte two = ((value >> 16) & 0xFF);
byte one = ((value >> 24) & 0xFF);
//Write the 4 bytes into the eeprom memory.
EEPROM.write(address, four);
EEPROM.write(address + 1, three);
EEPROM.write(address + 2, two);
EEPROM.write(address + 3, one);
}
//This function will return a 4 byte (32bit) long from the eeprom
//at the specified address to address + 3.
long EEPROMReadlong(long address) {
//Read the 4 bytes from the eeprom memory.
long four = EEPROM.read(address);
long three = EEPROM.read(address + 1);
long two = EEPROM.read(address + 2);
long one = EEPROM.read(address + 3);
//Return the recomposed long by using bitshift.
return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}
void sendCode(unsigned long code, int len) {
irsend.sendSony(code, len);
Serial.print("Sent Sony code: ");
Serial.println(code);
}
long buttonTimer = 0;
long longPressTime = 4000;
boolean buttonActive = false;
boolean longPressActive = false;
void loop() {
int buttonState = digitalRead(BUTTON_PIN);
if (buttonState == LOW) {
if (buttonActive == false) {
buttonActive = true;
buttonTimer = millis();
}
if (millis() - buttonTimer > longPressTime) {
if (longPressActive == false) {
longPressActive = true;
buttonTimer = millis();
// do long press things
Serial.println("Long press - Receive IR codes");
irrecv.enableIRIn(); // Re-enable receiver
} else {
Serial.println("2nd long press - Stop receiving IR codes");
longPressActive = false;
buttonTimer = millis();
}
}
} else {
if (buttonActive == true) {
if (longPressActive == false) {
// short press logic
Serial.println("Pressed, sending");
digitalWrite(STATUS_PIN, HIGH);
sendCode(codeValue, 24);
digitalWrite(STATUS_PIN, LOW);
delay(300); // Wait a bit between retransmissions
}
buttonActive = false;
}
if (longPressActive && irrecv.decode(&results)) {
digitalWrite(STATUS_PIN, HIGH);
storeCode(&results);
irrecv.resume(); // resume receiver
digitalWrite(STATUS_PIN, LOW);
}
}
}
|
Comments (0)
You can clone a snippet to your computer for local editing. Learn more.