Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ggaljoen/9bf39f90ab5c4a282917636e79b22769 to your computer and use it in GitHub Desktop.
Save ggaljoen/9bf39f90ab5c4a282917636e79b22769 to your computer and use it in GitHub Desktop.
Automatic Button Programming
// this sketch was brutally hacked together by TJ Bruno --- https://medium.com/@tbruno25
#include <Print.h>
#include <mcp_can.h>
#include <SPI.h>
#include <EEPROM.h>
#define CAN0_INT 2
MCP_CAN CAN0(10);
int s = 0;
int data;
byte i = 0;
byte idCount = 0;
byte buttonPress = 0;
unsigned char spd;
unsigned char len = 0;
unsigned char rxBuf[8];
unsigned long startMillis;
unsigned long endMillis;
unsigned long int rxId;
unsigned long int saveId;
unsigned long int currentMillis;
void(* resetFunc) (void) = 0;
bool duplicate;
String command;
void setup()
{
EEPROM.get(0, saveId);
EEPROM.get(19, spd);
EEPROM.get(20, data);
Serial.begin(115200);
if (CAN0.begin(MCP_ANY, spd, MCP_8MHZ) == CAN_OK)
{
CAN0.setMode(MCP_NORMAL);
pinMode(CAN0_INT, INPUT);
}
}
void loop()
{
if (Serial.available())
{
command = Serial.readStringUntil('\n');
if (command.equals("b"))
{
baud();
}
if (command.equals("p"))
{
program();
}
}
if (!digitalRead(2))
{
CAN0.readMsgBuf(&rxId, &len, rxBuf);
delay(5);
if (rxId == saveId)
{
s = 0;
for (byte x = 0; x < len; x++)
{
s += rxBuf[x];
}
if (s == data)
{
buttonPress++;
if (buttonPress == 1)
{
startMillis = millis();
}
if (buttonPress == 2)
{
endMillis = millis();
if (endMillis - startMillis <= 1000)
{
buttonPress = 0;
Serial.println("ACTIVATED!");
}
else
{
buttonPress--;
}
}
}
}
if (buttonPress == 1)
{
if (millis() - startMillis > 1000)
{
buttonPress--;
}
}
}
}
void program()
{
blank();
unsigned long int buf[100] = {};
Serial.println("Let car idle and hit [enter]\n");
while (0 == 0)
{
if (Serial.available())
{
command = Serial.readStringUntil('\n');
if (command.equals(""))
{
clear();
break;
}
}
}
Serial.print("Recording CAN ID's.");
while ((millis() - currentMillis) < 5000)
{
time();
if (!digitalRead(2))
{
CAN0.readMsgBuf(&rxId, &len, rxBuf);
delay(5);
for (byte x = 0; x < idCount; x++)
{
if (rxId == buf[x])
{
duplicate = true;
}
}
if (duplicate == false)
{
buf[idCount] = rxId;
idCount++;
currentMillis = millis();
}
duplicate = false;
}
}
byte start = idCount;
Serial.print("\n\n\nHit [enter] while continuously pressing the button.\n\n");
while (0 == 0)
{
if (Serial.available())
{
command = Serial.readStringUntil('\n');
if (command.equals(""))
{
clear();
break;
}
}
}
Serial.print("Recording.");
while ((millis() - currentMillis) < 5000)
{
time();
if (!digitalRead(2))
{
CAN0.readMsgBuf(&rxId, &len, rxBuf);
delay(5);
for (byte x = 0; x < idCount; x++)
{
if (rxId == buf[x])
{
duplicate = true;
}
}
if (duplicate == false)
{
buf[idCount] = rxId;
idCount++;
i++;
currentMillis = millis();
}
duplicate = false;
}
}
byte end = idCount;
int mBuf[idCount][2] = {{}, {}};
for (byte x = start; x < end; x++)
{
mBuf[x][0] = -1;
mBuf[x][1] = -1;
}
Serial.print("\n\n\n"); Serial.print(idCount); Serial.print(" different ID's recorded.\n\n");
delay(2500);
Serial.print(i); Serial.print(" possible options.\n\n\n");
delay(2500);
Serial.println("Hit [enter] then press and hold the button.\n\n");
while (0 == 0)
{
if (Serial.available())
{
command = Serial.readStringUntil('\n');
if (command.equals(""))
{
clear();
break;
}
}
}
Serial.print("Recording.");
while ((millis() - currentMillis) < 5000)
{
time();
if (!digitalRead(2))
{
CAN0.readMsgBuf(&rxId, &len, rxBuf);
delay(5);
for (byte x = start; x < end; x++)
{
if (rxId == buf[x])
{
s = 0;
for (byte z = 0; z < len; z++)
{
s += rxBuf[z];
}
if (mBuf[x][0] == -1)
{
mBuf[x][0] = s;
currentMillis = millis();
}
else if (s != mBuf[x][0])
{
buf[x] = 0;
}
}
}
}
}
Serial.print("\n\n\nHit [enter] then let go of the button.\n\n");
while (0 == 0)
{
if (Serial.available())
{
command = Serial.readStringUntil('\n');
if (command.equals(""))
{
clear();
break;
}
}
}
Serial.print("Recording.");
while ((millis() - currentMillis) < 5000)
{
time();
if (!digitalRead(2))
{
CAN0.readMsgBuf(&rxId, &len, rxBuf);
delay(5);
for (byte x = start; x < end; x++)
{
if (rxId == buf[x])
{
s = 0;
for (byte z = 0; z < len; z++)
{
s += rxBuf[z];
}
if (s != mBuf[x][0])
{
if (mBuf[x][1] == -1)
{
mBuf[x][1] = s;
currentMillis = millis();
}
else if (s != mBuf[x][1])
{
buf[x] = 0;
}
}
}
}
}
}
clear();
for (byte x = 0; x < idCount; x++)
{
// Serial.print("\n"); Serial.print(buf[x]); Serial.print(" "); Serial.print(mBuf[x][0]); Serial.print(" "); Serial.print(mBuf[x][1]);
if (mBuf[x][1] != 0)
{
saveId = buf[x];
data = mBuf[x][0];
}
}
EEPROM.put(0, saveId);
EEPROM.put(20, data);
Serial.print("\n\n\nButton programmed!");
delay(3000);
blank();
resetFunc();
}
void baud()
{
clear();
blank();
Serial.println(" Type the number that corresponds to the correct baudrate and press [enter]\n\n");
Serial.println(" [5]33.3k bps\n");
Serial.println(" [9]100k bps\n");
Serial.println(" [10]125k bps\n");
Serial.println(" [12]250k bps\n");
Serial.println(" [13]500k bps\n");
while (0 == 0)
{
if (Serial.available())
{
command = Serial.readStringUntil('\n');
spd = command.toInt();
if ((spd == 5) || (spd == 9) || (spd == 10) || (spd == 12) || (spd == 13))
{
Serial.print("\n\n\n Baudrate saved!");
EEPROM.put(19, spd);
delay(3000);
blank();
resetFunc();
}
}
}
}
void clear()
{
for (int x = 0; x < sizeof(CAN0.readMsgBuf); x++)
{
char t = CAN0.readMsgBuf(&rxId, &len, rxBuf);
}
i = 0;
duplicate = false;
currentMillis = millis();
}
void blank()
{
for (byte x = 0; x < 50; x++) Serial.println('\n');
}
void time()
{
static unsigned int long cycle = millis();
if ((millis() - cycle) > 2000)
{
Serial.print(".");
cycle = millis();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment