Initial commit
This commit is contained in:
BIN
Software/Switch/.MeyRule.cpp.swp
Normal file
BIN
Software/Switch/.MeyRule.cpp.swp
Normal file
Binary file not shown.
12
Software/Switch/.vscode/arduino.json
vendored
12
Software/Switch/.vscode/arduino.json
vendored
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"configuration": "pinout=48pin_standard,eeprom=keep,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader",
|
||||
"board": "MegaCoreX:megaavr:809",
|
||||
"sketch": "Switch.ino",
|
||||
"port": "COM6",
|
||||
"programmer": "jtag2updi"
|
||||
{
|
||||
"configuration": "pinout=48pin_standard,eeprom=keep,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader",
|
||||
"board": "MegaCoreX:megaavr:809",
|
||||
"sketch": "Switch.ino",
|
||||
"port": "COM6",
|
||||
"programmer": "jtag2updi"
|
||||
}
|
||||
1078
Software/Switch/.vscode/c_cpp_properties.json
vendored
1078
Software/Switch/.vscode/c_cpp_properties.json
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,255 +1,232 @@
|
||||
#include "MeyCan.h";
|
||||
#include <SPI.h>;
|
||||
#include <mcp2515.h>;
|
||||
|
||||
|
||||
PinState *MeyPin = NULL;
|
||||
CanInterface *CanBusses = NULL;
|
||||
uint16_t myDeviceId;
|
||||
byte _deviceTypeId = 0;
|
||||
byte _majorHardwareVersion = 0;
|
||||
byte _minorHardwareVersion = 0;
|
||||
|
||||
void SetupMeyPin(PinState *state)
|
||||
{
|
||||
pinMode(state->pin_id, OUTPUT);
|
||||
digitalWrite(state->pin_id, LOW);
|
||||
state->pin_state = false;
|
||||
}
|
||||
|
||||
void InitCanInterface(MCP2515 *interface, can_frame *frame) // can_frame is NULL. Reuse ForEach Method for smaller footprint
|
||||
{
|
||||
interface->reset();
|
||||
interface->setBitrate(CAN_500KBPS, MCP_8MHZ); //Sets CAN at speed 500KBPS and Clock 8MHz
|
||||
interface->setNormalMode();
|
||||
SendVersionPackage(interface);
|
||||
}
|
||||
|
||||
void ForEachCanInterface(void (*handle)(MCP2515 *canInterace))
|
||||
{
|
||||
CanBusses->ForEachInterface(handle);
|
||||
}
|
||||
|
||||
void SetupMeyCan(byte majorHardwareVersion, byte minorHardwareVersion, byte deviceTypeId)
|
||||
{
|
||||
_majorHardwareVersion = majorHardwareVersion;
|
||||
_minorHardwareVersion = minorHardwareVersion;
|
||||
_deviceTypeId = deviceTypeId;
|
||||
CalculateMyDeviceId();
|
||||
|
||||
if (MeyPin != NULL);
|
||||
MeyPin->ForEach(SetupMeyPin);
|
||||
|
||||
if (CanBusses != NULL)
|
||||
{
|
||||
CanBusses->ForEach(InitCanInterface, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void AddCanInterface(byte pinId)
|
||||
{
|
||||
MCP2515* newCanInterface = new MCP2515(pinId);
|
||||
CanInterface* canInterface = new CanInterface();
|
||||
canInterface->interface = newCanInterface;
|
||||
|
||||
if (CanBusses == NULL)
|
||||
CanBusses = canInterface;
|
||||
else
|
||||
CanBusses->AddCanInterface(canInterface);
|
||||
}
|
||||
|
||||
void SetMeyPin(byte index, byte meyPinId, byte pinId)
|
||||
{
|
||||
PinState* newState = new PinState();
|
||||
newState->Init(pinId, (byte) meyPinId);
|
||||
|
||||
if (MeyPin == NULL)
|
||||
MeyPin = newState;
|
||||
else
|
||||
MeyPin->AddPinState(newState);
|
||||
}
|
||||
|
||||
|
||||
bool CheckPinStatus(PinState * state)
|
||||
{
|
||||
if (!state->is_input)
|
||||
return false;
|
||||
|
||||
bool newValue = ReadPin(state);
|
||||
|
||||
|
||||
if (newValue != state->pin_state)
|
||||
{
|
||||
delay(10);
|
||||
newValue = ReadPin(state);
|
||||
if (newValue != state->pin_state)
|
||||
{
|
||||
state->pin_state = newValue;
|
||||
SendSwitchedTriggeredCanPackage(state->meyPinId, state->pin_state);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CheckMeyPinsTriggered()
|
||||
{
|
||||
MeyPin->ForEach(CheckPinStatus);
|
||||
}
|
||||
|
||||
bool ReadPin(PinState * state)
|
||||
{
|
||||
if (state->pin_id == PIN_PD2)
|
||||
return digitalReadFast(PIN_PD2);
|
||||
else if (state->pin_id == PIN_PC7)
|
||||
return digitalReadFast(PIN_PC7);
|
||||
else if (state->pin_id == PIN_PD1)
|
||||
return digitalReadFast(PIN_PD1);
|
||||
else if (state->pin_id == PIN_PD0)
|
||||
return digitalReadFast(PIN_PD0);
|
||||
else if (state->pin_id == PIN_PD6)
|
||||
return digitalReadFast(PIN_PD6);
|
||||
else if (state->pin_id == PIN_PD5)
|
||||
return digitalReadFast(PIN_PD5);
|
||||
else if (state->pin_id == PIN_PD4)
|
||||
return digitalReadFast(PIN_PD4);
|
||||
else if (state->pin_id == PIN_PD3)
|
||||
return digitalReadFast(PIN_PD3);
|
||||
else
|
||||
return digitalRead(state->pin_id);
|
||||
}
|
||||
|
||||
|
||||
void HandleFrame(can_frame *frame, MCP2515 *source)
|
||||
{
|
||||
CanBusses->ForEach(DoSendCanPkg, frame, source);
|
||||
HandleTriggerMeypinCanPackage(frame);
|
||||
}
|
||||
|
||||
void HandleTriggerMeypinCanPackage(can_frame *frame)
|
||||
{
|
||||
if (GetPackageType(frame->can_id) == TRIGGER_SWITCH_CAN_ID)
|
||||
{
|
||||
uint16_t adressedDeviceId = ((uint16_t )frame->data[0] << 8) | frame->data[1] ;
|
||||
if (adressedDeviceId != myDeviceId) return;
|
||||
|
||||
|
||||
byte meyPinId = frame->data[2];
|
||||
bool state = frame->data[3] > 0;
|
||||
|
||||
PinState *adressedPin = MeyPin->Find(meyPinId);
|
||||
|
||||
if (adressedPin != NULL)
|
||||
{
|
||||
if (adressedPin->is_input == true)
|
||||
{
|
||||
pinMode(adressedPin->pin_id, OUTPUT);
|
||||
adressedPin->is_input = false;
|
||||
}
|
||||
|
||||
bool pinChanged = adressedPin->pin_state != state;
|
||||
adressedPin->pin_state = state;
|
||||
|
||||
if (pinChanged) {
|
||||
digitalWrite(adressedPin->pin_id, state);
|
||||
SendSwitchedTriggeredCanPackage(adressedPin->meyPinId, state);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte CircularShift(byte b)
|
||||
{
|
||||
return (b << 1) | (b >> 7 & 1);
|
||||
}
|
||||
|
||||
uint16_t GetDeviceId(uint32_t canFrameId)
|
||||
{
|
||||
return canFrameId & 0xFFFF;
|
||||
}
|
||||
|
||||
uint16_t GetPackageType(uint32_t canFrameId)
|
||||
{
|
||||
return (canFrameId / 0x10000) & 0xFFF;
|
||||
}
|
||||
|
||||
byte GetDeviceIdLow() {
|
||||
return (SIGROW.SERNUM0 ^
|
||||
CircularShift(SIGROW.SERNUM2) << 1 ^
|
||||
CircularShift( CircularShift(SIGROW.SERNUM4)) ^
|
||||
CircularShift( CircularShift( CircularShift(SIGROW.SERNUM6))) ^
|
||||
CircularShift( CircularShift( CircularShift( CircularShift(SIGROW.SERNUM8)))));
|
||||
}
|
||||
|
||||
byte GetDeviceIdHigh() {
|
||||
return (SIGROW.SERNUM1 ^
|
||||
CircularShift(SIGROW.SERNUM3) << 1 ^
|
||||
CircularShift( CircularShift(SIGROW.SERNUM5)) ^
|
||||
CircularShift( CircularShift( CircularShift(SIGROW.SERNUM7))) ^
|
||||
CircularShift( CircularShift( CircularShift( CircularShift(SIGROW.SERNUM9)))));
|
||||
}
|
||||
|
||||
uint32_t CreateCanId(uint16_t commandId)
|
||||
{
|
||||
return ((((uint32_t)commandId) & 0xFFF) * 0x10000) | myDeviceId | CAN_EFF_FLAG;
|
||||
}
|
||||
|
||||
void SendVersionPackage(MCP2515 *interface)
|
||||
{
|
||||
can_frame toSend;
|
||||
toSend.can_id = CreateCanId(HELP_PACKAGE_CAN_ID);
|
||||
toSend.can_dlc = 5;
|
||||
|
||||
toSend.data[0] = SOFTWARE_VERSION_HIGH;
|
||||
toSend.data[1] = SOFTWARE_VERSION_LOW;
|
||||
toSend.data[2] = _majorHardwareVersion;
|
||||
toSend.data[3] = _minorHardwareVersion;
|
||||
toSend.data[4] = _deviceTypeId;
|
||||
|
||||
DoSendCanPkg(interface, &toSend);
|
||||
}
|
||||
|
||||
void BroadcastTriggerMeyPinCanPackage(uint16_t targetCanId, byte pinId, byte state)
|
||||
{
|
||||
can_frame toSend;
|
||||
|
||||
toSend.can_id = CreateCanId(TRIGGER_SWITCH_CAN_ID);
|
||||
toSend.can_dlc = 4;
|
||||
toSend.data[0] = (targetCanId & 0xFF00) >> 8;
|
||||
toSend.data[1] = targetCanId & 0xFF;
|
||||
toSend.data[2] = pinId;
|
||||
toSend.data[3] = state;
|
||||
|
||||
HandleFrame(&toSend, NULL);
|
||||
}
|
||||
|
||||
void SendSwitchedTriggeredCanPackage(byte pinId, int state)
|
||||
{
|
||||
can_frame toSend;
|
||||
toSend.can_id = CreateCanId(SWITCH_TRIGGERED_CAN_ID);
|
||||
toSend.can_dlc = 2;
|
||||
toSend.data[0] = pinId;
|
||||
toSend.data[1] = state;
|
||||
|
||||
DoSendCanPkg(&toSend);
|
||||
}
|
||||
|
||||
void DoSendCanPkg(can_frame *frame)
|
||||
{
|
||||
if (CanBusses != NULL)
|
||||
CanBusses->ForEach(DoSendCanPkg, frame);
|
||||
}
|
||||
|
||||
void DoSendCanPkg(MCP2515 *interface, can_frame *frame)
|
||||
{
|
||||
byte cnt = 0;
|
||||
while (interface->sendMessage(frame))
|
||||
{
|
||||
if (++cnt > 10) return;
|
||||
}
|
||||
}
|
||||
|
||||
void CalculateMyDeviceId()
|
||||
{
|
||||
myDeviceId = (GetDeviceIdHigh() << 8) | GetDeviceIdLow();
|
||||
}
|
||||
#include "MeyCan.h";
|
||||
#include <SPI.h>;
|
||||
#include <mcp2515.h>;
|
||||
|
||||
|
||||
PinState *MeyPin = NULL;
|
||||
CanInterface *CanBusses = NULL;
|
||||
uint16_t myDeviceId;
|
||||
byte _deviceTypeId = 0;
|
||||
byte _majorHardwareVersion = 0;
|
||||
byte _minorHardwareVersion = 0;
|
||||
void (*LocalPinChangedHandler)(can_frame *frame);
|
||||
|
||||
void SetupMeyPin(PinState *state) {
|
||||
pinMode(state->pin_id, OUTPUT);
|
||||
digitalWrite(state->pin_id, LOW);
|
||||
state->pin_state = false;
|
||||
}
|
||||
|
||||
void InitCanInterface(MCP2515 *interface, can_frame *frame) // can_frame is NULL. Reuse ForEach Method for smaller footprint
|
||||
{
|
||||
interface->reset();
|
||||
interface->setBitrate(CAN_1000KBPS, MCP_8MHZ); //Sets CAN at speed 500KBPS and Clock 8MHz
|
||||
interface->setNormalMode();
|
||||
SendVersionPackage(interface);
|
||||
}
|
||||
|
||||
void ForEachCanInterface(void (*handle)(MCP2515 *canInterace)) {
|
||||
CanBusses->ForEachInterface(handle);
|
||||
}
|
||||
|
||||
void SetupMeyCan(byte majorHardwareVersion, byte minorHardwareVersion, byte deviceTypeId) {
|
||||
_majorHardwareVersion = majorHardwareVersion;
|
||||
_minorHardwareVersion = minorHardwareVersion;
|
||||
_deviceTypeId = deviceTypeId;
|
||||
|
||||
if (MeyPin != NULL)
|
||||
;
|
||||
MeyPin->ForEach(SetupMeyPin);
|
||||
|
||||
if (CanBusses != NULL) {
|
||||
CanBusses->ForEach(InitCanInterface, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void AddCanInterface(byte pinId) {
|
||||
MCP2515 *newCanInterface = new MCP2515(pinId);
|
||||
CanInterface *canInterface = new CanInterface();
|
||||
canInterface->interface = newCanInterface;
|
||||
|
||||
if (CanBusses == NULL)
|
||||
CanBusses = canInterface;
|
||||
else
|
||||
CanBusses->AddCanInterface(canInterface);
|
||||
}
|
||||
|
||||
void AddLocalPinChangedHandler(void (*localPinChangedHandler)(can_frame *frame)) {
|
||||
LocalPinChangedHandler = localPinChangedHandler;
|
||||
}
|
||||
|
||||
void SetDevicedId(byte high, byte low) {
|
||||
myDeviceId = (high << 8) | low;
|
||||
}
|
||||
|
||||
void SetMeyPin(byte meyPinId, byte pinId) {
|
||||
PinState *newState = new PinState();
|
||||
newState->Init(pinId, (byte)meyPinId);
|
||||
|
||||
if (MeyPin == NULL)
|
||||
MeyPin = newState;
|
||||
else
|
||||
MeyPin->AddPinState(newState);
|
||||
}
|
||||
|
||||
|
||||
bool CheckPinStatus(PinState *state) {
|
||||
if (!state->is_input)
|
||||
return false;
|
||||
|
||||
bool newValue = ReadPin(state);
|
||||
|
||||
|
||||
if (newValue != state->pin_state) {
|
||||
delay(10);
|
||||
newValue = ReadPin(state);
|
||||
if (newValue != state->pin_state) {
|
||||
state->pin_state = newValue;
|
||||
SendSwitchedTriggeredCanPackage(state->meyPinId, state->pin_state);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CheckMeyPinsTriggered() {
|
||||
MeyPin->ForEach(CheckPinStatus);
|
||||
}
|
||||
|
||||
bool ReadPin(PinState *state) {
|
||||
return digitalRead(state->pin_id);
|
||||
}
|
||||
|
||||
|
||||
void HandleFrame(can_frame *frame, MCP2515 *source) {
|
||||
CanBusses->ForEach(DoSendCanPkg, frame, source);
|
||||
HandleTriggerMeypinCanPackage(frame);
|
||||
}
|
||||
|
||||
void HandleTriggerMeypinCanPackage(can_frame *frame) {
|
||||
|
||||
|
||||
if (GetPackageType(frame->can_id) == TRIGGER_SWITCH_CAN_ID) {
|
||||
|
||||
|
||||
uint16_t adressedDeviceId = ((uint16_t)frame->data[0] << 8) | frame->data[1];
|
||||
if (adressedDeviceId != myDeviceId) return;
|
||||
|
||||
|
||||
byte meyPinId = frame->data[2];
|
||||
bool state = frame->data[3] > 0;
|
||||
|
||||
PinState *adressedPin = MeyPin->Find(meyPinId);
|
||||
|
||||
if (adressedPin != NULL) {
|
||||
if (adressedPin->is_input == true) {
|
||||
pinMode(adressedPin->pin_id, OUTPUT);
|
||||
adressedPin->is_input = false;
|
||||
}
|
||||
|
||||
bool pinChanged = adressedPin->pin_state != state;
|
||||
adressedPin->pin_state = state;
|
||||
|
||||
if (pinChanged) {
|
||||
digitalWrite(adressedPin->pin_id, state);
|
||||
SendSwitchedTriggeredCanPackage(adressedPin->meyPinId, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byte CircularShift(byte b) {
|
||||
return (b << 1) | (b >> 7 & 1);
|
||||
}
|
||||
|
||||
uint16_t GetDeviceId(uint32_t canFrameId) {
|
||||
return canFrameId & 0xFFFF;
|
||||
}
|
||||
|
||||
uint16_t GetPackageType(uint32_t canFrameId) {
|
||||
return (canFrameId / 0x10000) & 0xFFF;
|
||||
}
|
||||
|
||||
|
||||
uint32_t CreateCanId(uint16_t commandId) {
|
||||
return ((((uint32_t)commandId) & 0xFFF) * 0x10000) | myDeviceId | CAN_EFF_FLAG;
|
||||
}
|
||||
|
||||
void SendVersionPackage(MCP2515 *interface) {
|
||||
can_frame toSend;
|
||||
toSend.can_id = CreateCanId(HELP_PACKAGE_CAN_ID);
|
||||
toSend.can_dlc = 5;
|
||||
|
||||
toSend.data[0] = SOFTWARE_VERSION_HIGH;
|
||||
toSend.data[1] = SOFTWARE_VERSION_LOW;
|
||||
toSend.data[2] = _majorHardwareVersion;
|
||||
toSend.data[3] = _minorHardwareVersion;
|
||||
toSend.data[4] = _deviceTypeId;
|
||||
|
||||
DoSendCanPkg(interface, &toSend);
|
||||
}
|
||||
|
||||
void BroadcastTriggerMeyPinCanPackage(uint16_t targetCanId, byte pinId, byte state) {
|
||||
can_frame toSend;
|
||||
|
||||
toSend.can_id = CreateCanId(TRIGGER_SWITCH_CAN_ID);
|
||||
toSend.can_dlc = 4;
|
||||
toSend.data[0] = (targetCanId & 0xFF00) >> 8;
|
||||
toSend.data[1] = targetCanId & 0xFF;
|
||||
toSend.data[2] = pinId;
|
||||
toSend.data[3] = state;
|
||||
|
||||
HandleFrame(&toSend, NULL);
|
||||
}
|
||||
|
||||
void BroadcastDebugPackage(uint8_t length, byte *data) {
|
||||
can_frame toSend;
|
||||
|
||||
toSend.can_id = CreateCanId(DEBUG_PKG_CAN_ID);
|
||||
toSend.can_dlc = length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
toSend.data[i] = data[i];
|
||||
}
|
||||
|
||||
HandleFrame(&toSend, NULL);
|
||||
}
|
||||
void BroadcastDebugPackage(byte b0, byte b1) {
|
||||
byte data[2];
|
||||
data[0] = b0;
|
||||
data[1] = b1;
|
||||
BroadcastDebugPackage(2, data);
|
||||
}
|
||||
void BroadcastDebugPackage(byte b0, byte b1, byte b2) {
|
||||
byte data[3];
|
||||
data[0] = b0;
|
||||
data[1] = b1;
|
||||
data[2] = b2;
|
||||
BroadcastDebugPackage(3, data);
|
||||
}
|
||||
|
||||
void SendSwitchedTriggeredCanPackage(byte pinId, int state) {
|
||||
can_frame toSend;
|
||||
toSend.can_id = CreateCanId(SWITCH_TRIGGERED_CAN_ID);
|
||||
toSend.can_dlc = 2;
|
||||
toSend.data[0] = pinId;
|
||||
toSend.data[1] = state;
|
||||
|
||||
DoSendCanPkg(&toSend);
|
||||
if (LocalPinChangedHandler) {
|
||||
LocalPinChangedHandler(&toSend);
|
||||
}
|
||||
}
|
||||
|
||||
void DoSendCanPkg(can_frame *frame) {
|
||||
if (CanBusses != NULL)
|
||||
CanBusses->ForEach(DoSendCanPkg, frame);
|
||||
}
|
||||
|
||||
void DoSendCanPkg(MCP2515 *interface, can_frame *frame) {
|
||||
byte cnt = 0;
|
||||
while (interface->sendMessage(frame)) {
|
||||
if (++cnt > 10) return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,128 +1,139 @@
|
||||
#ifndef MEYCAN_H
|
||||
#define MEYCAN_H
|
||||
|
||||
#include <SPI.h>
|
||||
#include <mcp2515.h>
|
||||
|
||||
typedef struct CanInterface
|
||||
{
|
||||
MCP2515 *interface;
|
||||
CanInterface *next = NULL;
|
||||
|
||||
void ForEachInterface(void (*handle)( MCP2515 *interface))
|
||||
{
|
||||
if (this->interface != NULL)
|
||||
handle(this->interface);
|
||||
|
||||
if (this->next != NULL)
|
||||
this->next->ForEachInterface(handle);
|
||||
}
|
||||
|
||||
void ForEach(void (*handle)( MCP2515 *interface, can_frame *frame), can_frame *frame, MCP2515* exclude = NULL)
|
||||
{
|
||||
if (this->interface != NULL && this->interface != exclude)
|
||||
handle(this->interface, frame);
|
||||
|
||||
if (this->next != NULL)
|
||||
this->next->ForEach(handle, frame, exclude);
|
||||
}
|
||||
|
||||
void AddCanInterface(CanInterface *newCanInterface)
|
||||
{
|
||||
if (next == NULL)
|
||||
{
|
||||
this->next = newCanInterface;
|
||||
newCanInterface->next = NULL;
|
||||
} else {
|
||||
next->AddCanInterface(newCanInterface);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef struct PinState
|
||||
{
|
||||
int pin_id;
|
||||
bool pin_state;
|
||||
bool is_input;
|
||||
byte meyPinId;
|
||||
PinState *next = NULL;
|
||||
|
||||
PinState() {}
|
||||
void Init(int pin_id, byte meyPinId)
|
||||
{
|
||||
this->pin_id = pin_id;
|
||||
this->pin_state = true;
|
||||
this->is_input = true;
|
||||
this->meyPinId = meyPinId;
|
||||
}
|
||||
|
||||
void AddPinState(PinState *nextPinState)
|
||||
{
|
||||
if (next == NULL)
|
||||
{
|
||||
this->next = nextPinState;
|
||||
nextPinState->next = NULL;
|
||||
} else {
|
||||
next->AddPinState(nextPinState);
|
||||
}
|
||||
}
|
||||
|
||||
PinState* Find(byte meyPinId)
|
||||
{
|
||||
if (this->meyPinId == meyPinId)
|
||||
return this;
|
||||
|
||||
if (this->next != NULL)
|
||||
return this->next->Find(meyPinId);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ForEach(void (*handle)(PinState *theState))
|
||||
{
|
||||
handle(this);
|
||||
if (this->next != NULL)
|
||||
this->next->ForEach(handle);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const byte SOFTWARE_VERSION_HIGH = 5;
|
||||
const byte SOFTWARE_VERSION_LOW = 0;
|
||||
const byte HARDWARE_VERSION_HIGH = 7;
|
||||
const byte HARDWARE_VERSION_LOW = 0;
|
||||
|
||||
const uint16_t HELP_PACKAGE_CAN_ID = 0x0FFFUL;
|
||||
const uint16_t SWITCH_TRIGGERED_CAN_ID = 0x0050;
|
||||
const uint16_t TRIGGER_SWITCH_CAN_ID = 0x0055;
|
||||
|
||||
void AddCanInterface(byte pinId);
|
||||
void SetMeyPin(byte index, byte meyPinId, byte pinId);
|
||||
|
||||
void SetupMeyCan(byte majorHardwareVersion, byte minorHardwareVersion, byte deviceTypeId);
|
||||
|
||||
void ForEachCanInterface(void (*handle)(MCP2515 *canInterace));
|
||||
bool ReadPin(PinState *state);
|
||||
bool CheckPinStatus(PinState * state);
|
||||
void CheckMeyPinsTriggered(); /* checks weather a meypin triggered and sends a can pkg is neccessary */
|
||||
void HandleFrame(can_frame *frame, MCP2515 *source);
|
||||
void HandleTriggerMeypinCanPackage(can_frame *frame);
|
||||
byte CircularShift(byte b);
|
||||
uint16_t GetDeviceId(uint32_t canFrameId);
|
||||
uint16_t GetPackageType(uint32_t canFrameId);
|
||||
byte GetDeviceIdLow();
|
||||
|
||||
byte GetDeviceIdHigh();
|
||||
|
||||
uint32_t CreateCanId(uint16_t commandId);
|
||||
void SendVersionPackage(MCP2515 *interface);
|
||||
|
||||
void SendSwitchedTriggeredCanPackage(byte pinId, int state);
|
||||
void BroadcastTriggerMeyPinCanPackage(uint16_t targetCanId, byte pinId, byte state);
|
||||
|
||||
void DoSendCanPkg(can_frame *frame);
|
||||
void DoSendCanPkg(MCP2515 *interface, can_frame *frame);
|
||||
|
||||
void CalculateMyDeviceId();
|
||||
|
||||
#endif
|
||||
#ifndef MEYCAN_H
|
||||
#define MEYCAN_H
|
||||
|
||||
#include <SPI.h>
|
||||
#include <mcp2515.h>
|
||||
|
||||
typedef struct CanInterface
|
||||
{
|
||||
MCP2515 *interface;
|
||||
CanInterface *next = NULL;
|
||||
|
||||
void ForEachInterface(void (*handle)( MCP2515 *interface))
|
||||
{
|
||||
if (this->interface != NULL)
|
||||
handle(this->interface);
|
||||
|
||||
if (this->next != NULL)
|
||||
this->next->ForEachInterface(handle);
|
||||
}
|
||||
|
||||
void ForEach(void (*handle)( MCP2515 *interface, can_frame *frame), can_frame *frame, MCP2515* exclude = NULL)
|
||||
{
|
||||
if (this->interface != NULL && this->interface != exclude)
|
||||
handle(this->interface, frame);
|
||||
|
||||
if (this->next != NULL)
|
||||
this->next->ForEach(handle, frame, exclude);
|
||||
}
|
||||
|
||||
void AddCanInterface(CanInterface *newCanInterface)
|
||||
{
|
||||
if (next == NULL)
|
||||
{
|
||||
this->next = newCanInterface;
|
||||
newCanInterface->next = NULL;
|
||||
} else {
|
||||
next->AddCanInterface(newCanInterface);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef struct PinState
|
||||
{
|
||||
int pin_id;
|
||||
bool pin_state;
|
||||
bool is_input;
|
||||
byte meyPinId;
|
||||
PinState *next = NULL;
|
||||
|
||||
PinState() {}
|
||||
void Init(int pin_id, byte meyPinId)
|
||||
{
|
||||
this->pin_id = pin_id;
|
||||
this->pin_state = true;
|
||||
this->is_input = true;
|
||||
this->meyPinId = meyPinId;
|
||||
}
|
||||
|
||||
void AddPinState(PinState *nextPinState)
|
||||
{
|
||||
if (next == NULL)
|
||||
{
|
||||
this->next = nextPinState;
|
||||
nextPinState->next = NULL;
|
||||
} else {
|
||||
next->AddPinState(nextPinState);
|
||||
}
|
||||
}
|
||||
|
||||
PinState* Find(byte meyPinId)
|
||||
{
|
||||
if (this->meyPinId == meyPinId)
|
||||
return this;
|
||||
|
||||
if (this->next != NULL)
|
||||
return this->next->Find(meyPinId);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ForEach(void (*handle)(PinState *theState))
|
||||
{
|
||||
handle(this);
|
||||
if (this->next != NULL)
|
||||
this->next->ForEach(handle);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const byte SOFTWARE_VERSION_HIGH = 5;
|
||||
const byte SOFTWARE_VERSION_LOW = 0;
|
||||
const byte HARDWARE_VERSION_HIGH = 7;
|
||||
const byte HARDWARE_VERSION_LOW = 0;
|
||||
|
||||
const uint16_t HELP_PACKAGE_CAN_ID = 0x0FFFUL;
|
||||
const uint16_t SWITCH_TRIGGERED_CAN_ID = 0x0050;
|
||||
const uint16_t TRIGGER_SWITCH_CAN_ID = 0x0055;
|
||||
const uint16_t DEBUG_PKG_CAN_ID = 0x0009;
|
||||
|
||||
void SetDevicedId(byte high, byte low);
|
||||
void SetMeyPin(byte meyPinId, byte pinId);
|
||||
|
||||
// we need to put the local change to the rules engine. otherwise local changes on a pin will not come to the rules state.
|
||||
void AddLocalPinChangedHandler(void (*localPinChangedHandler)(can_frame *frame));
|
||||
|
||||
|
||||
void AddCanInterface(byte pinId);
|
||||
|
||||
void SetupMeyCan(byte majorHardwareVersion, byte minorHardwareVersion, byte deviceTypeId);
|
||||
|
||||
void ForEachCanInterface(void (*handle)(MCP2515 *canInterace));
|
||||
bool ReadPin(PinState *state);
|
||||
bool CheckPinStatus(PinState * state);
|
||||
void CheckMeyPinsTriggered(); /* checks weather a meypin triggered and sends a can pkg is neccessary */
|
||||
void HandleFrame(can_frame *frame, MCP2515 *source);
|
||||
void HandleTriggerMeypinCanPackage(can_frame *frame);
|
||||
byte CircularShift(byte b);
|
||||
uint16_t GetDeviceId(uint32_t canFrameId);
|
||||
uint16_t GetPackageType(uint32_t canFrameId);
|
||||
byte GetDeviceIdLow();
|
||||
|
||||
byte GetDeviceIdHigh();
|
||||
|
||||
uint32_t CreateCanId(uint16_t commandId);
|
||||
void SendVersionPackage(MCP2515 *interface);
|
||||
|
||||
void SendSwitchedTriggeredCanPackage(byte pinId, int state);
|
||||
|
||||
|
||||
void BroadcastDebugPackage(byte b0, byte b1);
|
||||
void BroadcastDebugPackage(byte b0, byte b1, byte b2);
|
||||
void BroadcastTriggerMeyPinCanPackage(uint16_t targetCanId, byte pinId, byte state);
|
||||
|
||||
void DoSendCanPkg(can_frame *frame);
|
||||
void DoSendCanPkg(MCP2515 *interface, can_frame *frame);
|
||||
|
||||
void CalculateMyDeviceId();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,114 +1,117 @@
|
||||
#include "MeyRule.h"
|
||||
#include "MeyCan.h"
|
||||
#include <Arduino.h>
|
||||
#include <mcp2515.h>;
|
||||
|
||||
RemotePinInfo remotePinInfo = RemotePinInfo();
|
||||
Rule *rules = NULL;
|
||||
|
||||
void PutRule(Rule *rule)
|
||||
{
|
||||
if (rules == NULL)
|
||||
rules = rule;
|
||||
else
|
||||
rules->AddRule(rule);
|
||||
}
|
||||
|
||||
void AddSimple(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId)
|
||||
{
|
||||
Rule *rule = new Rule();
|
||||
|
||||
rule->sourceDevId = sourceDevId;
|
||||
rule->sourceMeyPinId = sourceMeyPinId;
|
||||
rule->targetDevId = targetDevId;
|
||||
rule->targetMeyPinId = targetMeyPinId;
|
||||
rule->toggle = false;
|
||||
rule->inverse = false;
|
||||
rule->lastPinState = false;
|
||||
|
||||
PutRule(rule);
|
||||
}
|
||||
|
||||
void AddToggle(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId)
|
||||
{
|
||||
Rule *rule = new Rule();
|
||||
|
||||
rule->sourceDevId = sourceDevId;
|
||||
rule->sourceMeyPinId = sourceMeyPinId;
|
||||
rule->targetDevId = targetDevId;
|
||||
rule->targetMeyPinId = targetMeyPinId;
|
||||
rule->toggle = true;
|
||||
rule->inverse = false;
|
||||
rule->lastPinState = false;
|
||||
|
||||
PutRule(rule);
|
||||
}
|
||||
|
||||
void AddToggleInverse(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId)
|
||||
{
|
||||
Rule *rule = new Rule();
|
||||
|
||||
rule->sourceDevId = sourceDevId;
|
||||
rule->sourceMeyPinId = sourceMeyPinId;
|
||||
rule->targetDevId = targetDevId;
|
||||
rule->targetMeyPinId = targetMeyPinId;
|
||||
rule->toggle = true;
|
||||
rule->inverse = true;
|
||||
rule->lastPinState = false;
|
||||
|
||||
PutRule(rule);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CheckRule(uint16_t deviceId, uint8_t dt, uint8_t state, Rule *rule)
|
||||
{
|
||||
RemotePinInfo *currentRemotePinInfo = remotePinInfo.FindOrAdd(rule->targetDevId);
|
||||
if (currentRemotePinInfo == NULL) return;
|
||||
|
||||
// check the new state with the last one. Needs to be done, as the UP switch might
|
||||
// send it multiple times like "01 01" "01 01" for a single tip.(antibeat)
|
||||
bool lastPinState = rule->lastPinState;
|
||||
bool pinState = dt > 0;
|
||||
|
||||
if (rule->triggeredOnce && lastPinState == pinState) return;
|
||||
rule->lastPinState = pinState;
|
||||
rule->triggeredOnce = true;
|
||||
|
||||
if (rule->inverse)
|
||||
pinState = !pinState;
|
||||
|
||||
if (rule->toggle)
|
||||
pinState = (currentRemotePinInfo->getPinState(rule->targetMeyPinId) ^ true);
|
||||
|
||||
BroadcastTriggerMeyPinCanPackage(rule->targetDevId, rule->targetMeyPinId, pinState);
|
||||
currentRemotePinInfo->setPinState(rule->targetMeyPinId, pinState);
|
||||
}
|
||||
|
||||
void HandleTriggered(can_frame *frame)
|
||||
{
|
||||
if (GetPackageType(frame->can_id) == SWITCH_TRIGGERED_CAN_ID)
|
||||
{
|
||||
RemotePinInfo *currentPinState = remotePinInfo.FindOrAdd(GetDeviceId(frame->can_id) );
|
||||
|
||||
if (currentPinState == NULL)
|
||||
return;
|
||||
|
||||
currentPinState->setPinState(frame->data[0], frame->data[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleRules(can_frame *frame)
|
||||
{
|
||||
HandleTriggered(frame);
|
||||
|
||||
if (rules == NULL) return;
|
||||
if (GetPackageType(frame->can_id) == SWITCH_TRIGGERED_CAN_ID)
|
||||
{
|
||||
uint16_t deviceId = GetDeviceId(frame->can_id);
|
||||
uint8_t dt = frame->data[1];
|
||||
uint8_t state = frame->data[0];
|
||||
|
||||
rules->Traverse(deviceId, dt, state, CheckRule);
|
||||
}
|
||||
}
|
||||
#include "MeyRule.h"
|
||||
#include "MeyCan.h"
|
||||
#include <Arduino.h>
|
||||
#include <mcp2515.h>;
|
||||
|
||||
RemotePinInfo remotePinInfo = RemotePinInfo();
|
||||
Rule *rules = NULL;
|
||||
|
||||
void PutRule(Rule *rule) {
|
||||
if (rules == NULL)
|
||||
rules = rule;
|
||||
else
|
||||
rules->AddRule(rule);
|
||||
}
|
||||
|
||||
void AddSimple(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId) {
|
||||
Rule *rule = new Rule();
|
||||
|
||||
rule->sourceDevId = sourceDevId;
|
||||
rule->sourceMeyPinId = sourceMeyPinId;
|
||||
rule->target.devId = targetDevId;
|
||||
rule->target.meyPinId = targetMeyPinId;
|
||||
rule->target.lastPinState = false;
|
||||
rule->toggle = false;
|
||||
rule->inverse = false;
|
||||
|
||||
PutRule(rule);
|
||||
}
|
||||
|
||||
void AddToggle(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId) {
|
||||
Rule *rule = new Rule();
|
||||
|
||||
rule->sourceDevId = sourceDevId;
|
||||
rule->sourceMeyPinId = sourceMeyPinId;
|
||||
rule->target.devId = targetDevId;
|
||||
rule->target.meyPinId = targetMeyPinId;
|
||||
rule->target.lastPinState = false;
|
||||
rule->toggle = true;
|
||||
rule->inverse = false;
|
||||
|
||||
PutRule(rule);
|
||||
}
|
||||
|
||||
void AddToggleInverse(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId) {
|
||||
Rule *rule = new Rule();
|
||||
|
||||
rule->sourceDevId = sourceDevId;
|
||||
rule->sourceMeyPinId = sourceMeyPinId;
|
||||
rule->target.devId = targetDevId;
|
||||
rule->target.meyPinId = targetMeyPinId;
|
||||
rule->target.lastPinState = false;
|
||||
rule->toggle = true;
|
||||
rule->inverse = true;
|
||||
|
||||
PutRule(rule);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CheckRule(uint16_t deviceId, uint8_t dt, uint8_t state, Rule *rule) {
|
||||
|
||||
|
||||
RemotePinInfo *currentRemotePinInfo = remotePinInfo.FindOrAdd(rule->target.devId);
|
||||
|
||||
if (currentRemotePinInfo == NULL) return;
|
||||
|
||||
// check the new state with the last one. Needs to be done, as the UP switch might
|
||||
// send it multiple times like "01 01" "01 01" for a single tip.(antibeat)
|
||||
bool lastPinState = rule->target.lastPinState;
|
||||
bool pinState = dt > 0;
|
||||
|
||||
if (rule->triggeredOnce && lastPinState == pinState) return;
|
||||
|
||||
rule->target.lastPinState = pinState;
|
||||
rule->triggeredOnce = true;
|
||||
|
||||
if (rule->inverse)
|
||||
pinState = !pinState;
|
||||
|
||||
if (rule->toggle)
|
||||
pinState = (currentRemotePinInfo->getPinState(rule->target.meyPinId) ^ true);
|
||||
|
||||
currentRemotePinInfo->setPinState(rule->target.meyPinId, pinState);
|
||||
BroadcastTriggerMeyPinCanPackage(rule->target.devId, rule->target.meyPinId, pinState);
|
||||
}
|
||||
|
||||
void HandleTriggered(can_frame *frame) {
|
||||
if (GetPackageType(frame->can_id) == SWITCH_TRIGGERED_CAN_ID) {
|
||||
RemotePinInfo *currentPinState = remotePinInfo.FindOrAdd(GetDeviceId(frame->can_id));
|
||||
|
||||
if (currentPinState == NULL) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
currentPinState->setPinState(frame->data[0], frame->data[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void SetLocalPinState(can_frame *frame)
|
||||
{
|
||||
HandleTriggered(frame);
|
||||
}
|
||||
|
||||
void HandleRules(can_frame *frame) {
|
||||
|
||||
if (rules != NULL) {
|
||||
if (GetPackageType(frame->can_id) == SWITCH_TRIGGERED_CAN_ID) {
|
||||
uint16_t deviceId = GetDeviceId(frame->can_id);
|
||||
uint8_t dt = frame->data[1];
|
||||
uint8_t state = frame->data[0];
|
||||
|
||||
rules->Traverse(deviceId, dt, state, CheckRule);
|
||||
}
|
||||
}
|
||||
HandleTriggered(frame);
|
||||
}
|
||||
|
||||
@@ -1,113 +1,107 @@
|
||||
#ifndef MEYRULE_H
|
||||
#define MEYRULE_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <mcp2515.h>;
|
||||
|
||||
struct Rule
|
||||
{
|
||||
uint16_t sourceDevId;
|
||||
byte sourceMeyPinId;
|
||||
uint16_t targetDevId;
|
||||
byte targetMeyPinId;
|
||||
bool toggle;
|
||||
bool inverse;
|
||||
Rule *nextRule = NULL;
|
||||
bool lastPinState = false;
|
||||
bool triggeredOnce = false;
|
||||
|
||||
void AddRule(Rule *rule)
|
||||
{
|
||||
if (this->nextRule == NULL)
|
||||
{
|
||||
this->nextRule = rule;
|
||||
rule->nextRule = NULL;
|
||||
} else {
|
||||
this->nextRule->AddRule(rule);
|
||||
}
|
||||
}
|
||||
|
||||
void Traverse( uint16_t deviceId, uint8_t dt, uint8_t state, void (*handle)(uint16_t, uint8_t, uint8_t, Rule*))
|
||||
{
|
||||
|
||||
if ( this->sourceDevId == deviceId && this->sourceMeyPinId == state)
|
||||
handle(deviceId, dt, state, this);
|
||||
|
||||
if (this->nextRule != NULL)
|
||||
this->nextRule->Traverse(deviceId, dt, state, handle);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef struct RemotePinInfo
|
||||
{
|
||||
const byte MAX_REMOTE_PIN_COUNT = 64;
|
||||
uint16_t DeviceId = 0; // the id of the device
|
||||
uint8_t pinState = 0; // bitmap of 8 MeyPin states of the device. 0000 0100, MeyPin #3 is HIGH in this example
|
||||
RemotePinInfo *next = NULL;
|
||||
|
||||
bool getPinState(byte meyPin)
|
||||
{
|
||||
return (this->pinState >> (meyPin - 1)) & 1;
|
||||
}
|
||||
|
||||
void setPinState(byte meyPin, bool state)
|
||||
{
|
||||
if (state)
|
||||
this->pinState = this->pinState | (1 << (meyPin - 1)); // 0001 0000
|
||||
else
|
||||
this->pinState = this->pinState & (~(1 << (meyPin - 1))); // 1110 1111 -> not
|
||||
}
|
||||
|
||||
|
||||
int16_t Count()
|
||||
{
|
||||
if (this->next == NULL) return 1;
|
||||
return this->next->Count() + 1;
|
||||
}
|
||||
|
||||
RemotePinInfo* FindOrAdd(uint16_t deviceId, byte count = 0)
|
||||
{
|
||||
if (count > MAX_REMOTE_PIN_COUNT)
|
||||
return NULL;
|
||||
|
||||
|
||||
if (this->DeviceId == 0 && this->pinState == 0)
|
||||
{
|
||||
this->DeviceId = deviceId;
|
||||
this->pinState = 0;
|
||||
}
|
||||
|
||||
if (this->DeviceId == deviceId)
|
||||
{
|
||||
//ToggleDebug();
|
||||
return this;
|
||||
}
|
||||
|
||||
if (next != NULL)
|
||||
{
|
||||
return next->FindOrAdd(deviceId, count + 1);
|
||||
}
|
||||
|
||||
RemotePinInfo *theNext = new RemotePinInfo;
|
||||
theNext->DeviceId = deviceId;
|
||||
theNext->pinState = 0;
|
||||
theNext->next = NULL;
|
||||
|
||||
this->next = theNext;
|
||||
return this->next;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
extern RemotePinInfo remotePinInfo;
|
||||
extern Rule *rules;
|
||||
|
||||
void AddSimple(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId);
|
||||
void AddToggle(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId);
|
||||
void AddToggleInverse(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId);
|
||||
void HandleRules(can_frame *frame);
|
||||
void PutRule(Rule *rule);
|
||||
void CheckRule(uint16_t deviceId, uint8_t dt, uint8_t state, Rule *rule);
|
||||
#endif
|
||||
#ifndef MEYRULE_H
|
||||
#define MEYRULE_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <mcp2515.h>;
|
||||
|
||||
struct TargetPin{
|
||||
uint16_t devId;
|
||||
byte meyPinId;
|
||||
bool lastPinState = false;
|
||||
|
||||
};
|
||||
|
||||
struct Rule {
|
||||
uint16_t sourceDevId;
|
||||
byte sourceMeyPinId;
|
||||
TargetPin target = TargetPin();
|
||||
bool toggle;
|
||||
bool inverse;
|
||||
Rule *nextRule = NULL;
|
||||
bool triggeredOnce = false;
|
||||
|
||||
void AddRule(Rule *rule) {
|
||||
if (this->nextRule == NULL) {
|
||||
this->nextRule = rule;
|
||||
rule->nextRule = NULL;
|
||||
} else {
|
||||
this->nextRule->AddRule(rule);
|
||||
}
|
||||
}
|
||||
|
||||
void Traverse(uint16_t deviceId, uint8_t dt, uint8_t state, void (*handle)(uint16_t, uint8_t, uint8_t, Rule *)) {
|
||||
|
||||
if (this->sourceDevId == deviceId && this->sourceMeyPinId == state)
|
||||
handle(deviceId, dt, state, this);
|
||||
|
||||
if (this->nextRule != NULL)
|
||||
this->nextRule->Traverse(deviceId, dt, state, handle);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef struct RemotePinInfo {
|
||||
const byte MAX_REMOTE_PIN_COUNT = 64;
|
||||
uint16_t DeviceId = 0; // the id of the device
|
||||
uint8_t pinState = 0; // bitmap of 8 MeyPin states of the device. 0000 0100, MeyPin #3 is HIGH in this example
|
||||
RemotePinInfo *next = NULL;
|
||||
|
||||
bool getPinState(byte meyPin) {
|
||||
return (this->pinState >> (meyPin - 1)) & 1;
|
||||
}
|
||||
|
||||
void setPinState(byte meyPin, bool state) {
|
||||
if (state)
|
||||
this->pinState = this->pinState | (1 << (meyPin - 1)); // 0001 0000
|
||||
else
|
||||
this->pinState = this->pinState & (~(1 << (meyPin - 1))); // 1110 1111 -> not
|
||||
}
|
||||
|
||||
|
||||
int16_t Count() {
|
||||
if (this->next == NULL) return 1;
|
||||
return this->next->Count() + 1;
|
||||
}
|
||||
|
||||
RemotePinInfo *FindOrAdd(uint16_t deviceId, byte count = 0) {
|
||||
if (count > MAX_REMOTE_PIN_COUNT)
|
||||
return NULL;
|
||||
|
||||
|
||||
if (this->DeviceId == 0 && this->pinState == 0) {
|
||||
this->DeviceId = deviceId;
|
||||
this->pinState = 0;
|
||||
}
|
||||
|
||||
if (this->DeviceId == deviceId) {
|
||||
//ToggleDebug();
|
||||
return this;
|
||||
}
|
||||
|
||||
if (next != NULL) {
|
||||
return next->FindOrAdd(deviceId, count + 1);
|
||||
}
|
||||
|
||||
RemotePinInfo *theNext = new RemotePinInfo;
|
||||
theNext->DeviceId = deviceId;
|
||||
theNext->pinState = 0;
|
||||
theNext->next = NULL;
|
||||
|
||||
this->next = theNext;
|
||||
return this->next;
|
||||
}
|
||||
};
|
||||
|
||||
extern RemotePinInfo remotePinInfo;
|
||||
extern Rule *rules;
|
||||
|
||||
void SetLocalPinState(can_frame *frame);
|
||||
|
||||
void AddSimple(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId);
|
||||
void AddToggle(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId);
|
||||
void AddToggleInverse(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId);
|
||||
void HandleRules(can_frame *frame);
|
||||
void PutRule(Rule *rule);
|
||||
void CheckRule(uint16_t deviceId, uint8_t dt, uint8_t state, Rule *rule);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,96 +1,114 @@
|
||||
#include <SPI.h>;
|
||||
#include <mcp2515.h>;
|
||||
#include "MeyCan.h";
|
||||
#include "MeyRule.h";
|
||||
|
||||
const int16_t SW_FLUR = 0XD238;
|
||||
const int16_t SW_ANBAU = 0x87A9;
|
||||
const int16_t SW_WOHNZIMMER = 0x87CA;
|
||||
|
||||
const int16_t UP_WOHNZIMMER_TUER = 0x051F;
|
||||
const int16_t UP_WOHNZIMMER_TERASSE = 0x05df;
|
||||
const int16_t UP_FLUR_EINGANG = 0x0769;
|
||||
const int16_t UP_BUERO = 0x1177;
|
||||
const int16_t UP_FLUR_BUERO = 0x05A1;
|
||||
const int16_t UP_FLUR_KUECHE = 0x01EF;
|
||||
const int16_t UP_KINDERZIMMER = 0x0196;
|
||||
const int16_t UP_FLUR_ELTERN = 0x0632;
|
||||
const int16_t UP_KUECHE_FLUR = 0x07F5;
|
||||
const int16_t UP_KUECHE_BAD = 0x0585;
|
||||
|
||||
struct can_frame incomingCanFrame;
|
||||
|
||||
void setup() {
|
||||
SPI.begin();
|
||||
|
||||
|
||||
// AddToggleInverse(UP_WOHNZIMMER_TUER, 5, SW_WOHNZIMMER, 4); // Lichtschalter Wohnzimmer Licht 1
|
||||
// AddToggleInverse(UP_WOHNZIMMER_TUER, 5, SW_WOHNZIMMER, 3); // Lichtschalter Wohnzimmer Licht 2
|
||||
// AddToggle(UP_WOHNZIMMER_TERASSE, 1, SW_WOHNZIMMER, 4); // Licht 1 von Terassenschalter
|
||||
// AddToggle(UP_WOHNZIMMER_TERASSE, 1, SW_WOHNZIMMER, 3); // Licht 2 von Terassenschalter
|
||||
//
|
||||
// AddToggle(0x0769, 1, SW_WOHNZIMMER, 7); // Eingangstür Flur Licht 2
|
||||
// AddToggle(0x0769, 1, SW_FLUR, 1); //Eingangstür Flur Licht 1
|
||||
//
|
||||
// AddToggle(UP_WOHNZIMMER_TUER, 3, SW_WOHNZIMMER, 1); // Licht 1 Wochzimmer Eingangstür
|
||||
// AddToggle(UP_WOHNZIMMER_TUER, 4, SW_WOHNZIMMER, 2); // Licht 2 Wochzimmer Eingangstür
|
||||
//
|
||||
// AddToggle(0x1177, 1, SW_WOHNZIMMER, 6); // Licht Papa Büro
|
||||
// AddToggle(0x05A1, 1, SW_WOHNZIMMER, 7); // Flurlicht von Papas Büro
|
||||
// AddToggle(0x05A1, 1, SW_FLUR, 1); // Flurlicht von Papas Büro
|
||||
// AddToggle(0x01EF, 1, SW_WOHNZIMMER, 7); // Flurlicht von Papas Büro
|
||||
// AddToggle(0x01EF, 1, SW_FLUR, 1); // Flurlicht von Papas Büro
|
||||
// AddToggle(0x0196, 3, SW_WOHNZIMMER, 7); // Flurlicht von Papas Büro
|
||||
// AddToggle(0x0196, 3, SW_FLUR, 1); // Flurlicht von Papas Büro
|
||||
// AddToggle(0x0632, 1, SW_FLUR, 5); // Flurlicht von Papas Büro
|
||||
//
|
||||
// AddToggle(UP_WOHNZIMMER_TUER, 2, SW_FLUR, 2); // Linus Zimmer hoch aus Wohnzimmer
|
||||
// AddToggle(UP_WOHNZIMMER_TUER, 1, SW_FLUR, 3); // Linus Zimmer runter hoch aus Wohnzimmer
|
||||
//
|
||||
// AddToggle(0x0769, 2, SW_FLUR, 4); // Linus Zimmer runter hoch aus Wohnzimmer
|
||||
//
|
||||
//
|
||||
// AddToggle(UP_KUECHE_FLUR, 1, SW_ANBAU, 2);
|
||||
// AddToggle(UP_KUECHE_FLUR, 2, SW_ANBAU, 3);
|
||||
// AddToggle(UP_KUECHE_BAD, 1, SW_ANBAU, 2);
|
||||
// AddToggle(UP_KUECHE_BAD, 3, SW_ANBAU, 1);
|
||||
// AddToggle(UP_KUECHE_BAD, 2, SW_ANBAU, 4);
|
||||
|
||||
|
||||
_PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL.MCLKCTRLA | 1 << 7);
|
||||
|
||||
delay(10); // a bit delay for mcp2515 to get the clock
|
||||
|
||||
|
||||
SetMeyPin(0, 1, PIN_PC7);
|
||||
SetMeyPin(1, 2, PIN_PC6);
|
||||
SetMeyPin(2, 3, PIN_PC5);
|
||||
SetMeyPin(3, 4, PIN_PC4);
|
||||
SetMeyPin(4, 5, PIN_PC3);
|
||||
SetMeyPin(5, 6, PIN_PC2);
|
||||
SetMeyPin(6, 7, PIN_PC1);
|
||||
SetMeyPin(7, 8, PIN_PC0);
|
||||
|
||||
AddCanInterface(PIN_PA2);
|
||||
AddCanInterface(PIN_PA3);
|
||||
AddCanInterface(PIN_PB0);
|
||||
AddCanInterface(PIN_PB1);
|
||||
|
||||
|
||||
SetupMeyCan(7, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
ForEachCanInterface(CheckCanInterface);
|
||||
}
|
||||
|
||||
void CheckCanInterface(MCP2515 *interface)
|
||||
{
|
||||
if (interface->readMessage(&incomingCanFrame) == MCP2515::ERROR_OK)
|
||||
{
|
||||
HandleFrame(&incomingCanFrame, interface);
|
||||
HandleRules(&incomingCanFrame);
|
||||
}
|
||||
}
|
||||
#include <SPI.h>;
|
||||
#include <mcp2515.h>;
|
||||
#include "MeyCan.h";
|
||||
#include "MeyRule.h";
|
||||
|
||||
#define PIN8 8
|
||||
#define PIN9 9
|
||||
|
||||
const int16_t SW_FLUR = 0XD238;
|
||||
const int16_t SW_ANBAU = 0x87A9;
|
||||
const int16_t SW_WOHNZIMMER = 0x87CA;
|
||||
const int16_t SW_TERRASSE = 0x618A;
|
||||
|
||||
|
||||
const int16_t UP_WOHNZIMMER_TUER = 0x051F; // [X X]
|
||||
const int16_t UP_WOHNZIMMER_TERASSE = 0x05df;
|
||||
const int16_t UP_FLUR_EINGANG = 0x0769; // [X]
|
||||
const int16_t UP_BUERO = 0x1177;
|
||||
const int16_t UP_FLUR_BUERO = 0x05A1; // [X]
|
||||
const int16_t UP_FLUR_KUECHE = 0x01EF;
|
||||
const int16_t UP_KINDERZIMMER = 0x0196; // [X X]
|
||||
const int16_t UP_FLUR_ELTERN = 0x0632;
|
||||
const int16_t UP_ELTERN = 0x08AE;
|
||||
const int16_t UP_KUECHE_FLUR = 0x07F5; // [X]
|
||||
const int16_t UP_KUECHE_BAD = 0x0585; // [X X]
|
||||
|
||||
struct can_frame incomingCanFrame;
|
||||
|
||||
/*
|
||||
Software matching Hardware of meycan v8.1
|
||||
*/
|
||||
void setup() {
|
||||
SPI.begin();
|
||||
|
||||
|
||||
AddToggle(UP_WOHNZIMMER_TUER, 1, SW_WOHNZIMMER, 5);
|
||||
AddToggle(UP_WOHNZIMMER_TUER, 1, SW_WOHNZIMMER, 6);
|
||||
AddSimple(UP_WOHNZIMMER_TUER, 2, SW_WOHNZIMMER, 7);
|
||||
AddSimple(UP_WOHNZIMMER_TUER, 3, SW_WOHNZIMMER, 8);
|
||||
|
||||
|
||||
AddToggle(UP_KINDERZIMMER, 3, SW_FLUR, 6);
|
||||
AddToggle(UP_KINDERZIMMER, 3, SW_WOHNZIMMER, 2);
|
||||
AddToggle(UP_KINDERZIMMER, 2, SW_FLUR, 3);
|
||||
AddSimple(UP_KINDERZIMMER, 4, SW_FLUR, 4);
|
||||
AddSimple(UP_KINDERZIMMER, 1, SW_FLUR, 5);
|
||||
|
||||
|
||||
AddToggle(UP_FLUR_EINGANG, 1, SW_FLUR, 1);
|
||||
AddToggle(UP_FLUR_EINGANG, 2, SW_FLUR, 6);
|
||||
AddToggle(UP_FLUR_EINGANG, 2, SW_WOHNZIMMER, 2);
|
||||
|
||||
AddToggle(UP_ELTERN, 1, SW_FLUR, 2);
|
||||
|
||||
AddToggle(UP_BUERO, 1, SW_WOHNZIMMER, 3);
|
||||
|
||||
AddToggle(UP_FLUR_BUERO, 1, SW_FLUR, 6);
|
||||
AddToggle(UP_FLUR_BUERO, 1, SW_WOHNZIMMER, 2);
|
||||
|
||||
AddToggle (UP_WOHNZIMMER_TERASSE, 1, SW_WOHNZIMMER, 7); // Licht 1 von Terassenschalter
|
||||
AddToggle (UP_WOHNZIMMER_TERASSE, 2, SW_WOHNZIMMER, 8); // Licht
|
||||
AddToggle (UP_WOHNZIMMER_TERASSE, 3, SW_TERRASSE, 2); // Pergola
|
||||
|
||||
/// RULE FOR SWITCH WOHNZIMMER (BOTH) OF TERASSE
|
||||
// AddSimple (UP_WOHNZIMMER_TERASSE, 3, SW_WOHNZIMMER, 5); // Eingangstür Flur Licht 2
|
||||
// AddSimple (UP_WOHNZIMMER_TERASSE, 3, SW_WOHNZIMMER, 6); // Eingangstür Flur Licht 2
|
||||
|
||||
|
||||
AddToggle(UP_KUECHE_FLUR, 1, SW_ANBAU, 3);
|
||||
AddToggle(UP_KUECHE_FLUR, 2, SW_ANBAU, 2);
|
||||
AddToggle(UP_KUECHE_BAD, 1, SW_ANBAU, 3);
|
||||
AddToggle(UP_KUECHE_BAD, 2, SW_ANBAU, 1);
|
||||
AddToggle(UP_KUECHE_BAD, 3, SW_ANBAU, 4);
|
||||
|
||||
AddToggle(UP_FLUR_KUECHE, 1, SW_FLUR, 6);
|
||||
AddToggle(UP_FLUR_KUECHE, 1, SW_WOHNZIMMER, 2);
|
||||
|
||||
|
||||
SetMeyPin(1, PIN3);
|
||||
SetMeyPin(2, PIN5);
|
||||
SetMeyPin(3, PIN7);
|
||||
SetMeyPin(4, PIN9);
|
||||
SetMeyPin(5, PIN8);
|
||||
SetMeyPin(6, PIN6);
|
||||
SetMeyPin(7, PIN4);
|
||||
SetMeyPin(8, PIN2);
|
||||
|
||||
SetDevicedId(0x87, 0xCA);
|
||||
AddLocalPinChangedHandler(SetLocalPinStateAdapter);
|
||||
|
||||
AddCanInterface(PIN_A0);
|
||||
AddCanInterface(PIN_A1);
|
||||
AddCanInterface(PIN_A2);
|
||||
AddCanInterface(PIN_A3);
|
||||
|
||||
SetupMeyCan(8, 0, 2);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
ForEachCanInterface(CheckCanInterface);
|
||||
}
|
||||
|
||||
|
||||
void SetLocalPinStateAdapter(can_frame *frame)
|
||||
{
|
||||
SetLocalPinState(frame);
|
||||
}
|
||||
|
||||
void CheckCanInterface(MCP2515 *interface) {
|
||||
if (interface->readMessage(&incomingCanFrame) == MCP2515::ERROR_OK) {
|
||||
HandleFrame(&incomingCanFrame, interface);
|
||||
HandleRules(&incomingCanFrame);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user