Initial commit

This commit is contained in:
Martin Linkwitz - NUC
2026-04-02 14:25:39 +02:00
parent ea3b0f29ea
commit c7adbcd1c7
110 changed files with 189727 additions and 33726 deletions

View File

@@ -1,49 +1,67 @@
MeyCan: PROTOCOL
ArbitartionID:
|<-- 13 bits -->| |<-- 16 bits -->|
COMMAND DEVICE_ID
ABC 0x14 6A
COMMAND: The Command or data type transfered. -> 2^11 = 2048 Package-Types
DEVICE_ID: A unique id for the device within the CAN Network (Home) -> 2^18 bit = 65.536 devices allowed
Packages
---------------------------------
0xF00: HELLO->ADOPT
Payload:
2 bytes | Byte -> Software-Version (1.0)
2 bytes | Byte -> Hw Version (4.0)
2 bytes | DeviceId -> DeviceId Explicit
0x050: Input Switch Triggered
-> Broadcast
---------------------------------
Payload:
1 byte| PinId -> Id of the pin of the local board.
1 byte| State -> 1 for Switched, 0 for Unswitched
0x055: Command Set Switch
-> Broadcast
---------------------------------
2 bytes | TargetDeviceId -> The id of the device to set the pin of
1 byte | PinId -> Idof the pin of the board
1 byte | state -> 1 to swtich on, 0 to switch off
0x010: Request Remote Pin State
-> Broadcast
---------------------------------
2 bytes | TargetDeviceId -> The id of the board to request the remote pin states from. This needs to be a control device (not UP)
1 byte | 0: Request
| 1: Response
DAT |
-- n Items of format ------------
* 2 byte: DeviceId
* 1 byte: The State
MeyCan: PROTOCOL
ArbitartionID:
|<-- 13 bits -->| |<-- 16 bits -->|
COMMAND DEVICE_ID
ABC 0x14 6A
COMMAND: The Command or data type transfered. -> 2^11 = 2048 Package-Types
DEVICE_ID: A unique id for the device within the CAN Network (Home) -> 2^18 bit = 65.536 devices allowed
Packages
---------------------------------
0xF00: HELLO->ADOPT
Payload:
2 bytes | Byte -> Software-Version (1.0)
2 bytes | Byte -> Hw Version (4.0)
1 bytes | DeviceTypeId
| 1: Switch
| 2: Switch + Rule
| 3: UP
0x050: Input Switch Triggered
-> Broadcast
---------------------------------
Payload:
1 byte| PinId -> Id of the pin of the local board.
1 byte| State -> 1 for Switched, 0 for Unswitched
0x055: Command Set Switch
-> Broadcast
---------------------------------
2 bytes | TargetDeviceId -> The id of the device to set the pin of
1 byte | PinId -> Idof the pin of the board
1 byte | state -> 1 to swtich on, 0 to switch off
0x010: Request Remote Pin State
-> Broadcast
---------------------------------
2 bytes | TargetDeviceId -> The id of the board to request the remote pin states from. This needs to be a control device (not UP)
1 byte | 0: Request
| 1: Response
DAT |
-- n Items of format ------------
* 2 byte: DeviceId
* 1 byte: The State
0x009: Debug
-> Debug Package
----------------------------------
some debug information
0xAA AudioStream #1
0xAB AudioStream #2
0xBA AudioStream #3
0xBB AudioStream #4
0xAAXX -> XX = Sequence Counter
0xY -> Reserve - Flag
|<-- 4 bits -->| |<-- 24 bits -->|
-> 3 Byte / Paket

Binary file not shown.

View File

@@ -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"
}

File diff suppressed because it is too large Load Diff

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -1,68 +1,68 @@
Testfälle Meycan Switch
PreCons for each:
GIVEN XX XX is the deviceId of the target device
GIVEN YY YY is another device id, which is NOT XX XX
GIVEN 2nd CAN Debug Device on another CanBus of switch
1) A MeyPin can be triggered directly (repeat Test for all MeyPins and each CAN Bus Interface specified)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 01 01 -> (MeyPin1 Should switch to on)
THEN The MeyPin 1 should trigger
THEN you receive a message 00 50 XX XX | 01 01
THEN 2nd device should receive 2 messages
* 00 50 XX XX | 01 01
* 00 55 11 11 | XX XX 01 01
1a) A MeyPin trigger is effecltess, if only set
GIVEN the above testcast
WHEN Send CAN Pkg 00 55 11 11 | XX XX 01 01
THEN Nothing changed
THEN you dont receive a message
THEN 2nd device should receive 00 55 11 11 | XX XX 01 01
WHEN Send CAN Pkg 00 55 11 11 | XX XX 01 00 -> (MeyPin1 Should switch to off)
THEN The MeyPin 1 should switch to OFF
THEN you receive a message 00 50 XX XX | 01 00
THEN 2nd device should receive 2 messages
* 00 50 XX XX | 01 00
* 00 55 11 11 | XX XX 01 00
2) A MeyPin is not triggered, if the device id dont match
WHEN Send CAN Pkg 00 55 11 11 | YY YY 01 01
THEN None of the pins of the device triggered
THEN you receive no message
THEN 2nd device should receive 1 messages
* 00 55 11 11 | XX XX 01 01
3) A MeyPin is not triggered, if the Package Type dont match
WHEN Send CAN Pkg 50 00 11 11 | YY YY 01 01
THEN None of the pins of the device triggered
THEN you receive no message
THEN 2nd device should receive 1 messages
* 50 00 11 11 | XX XX 01 01
3) A MeyPin is not triggered, if the MeyPin is above 8 (max pins)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 09 01
THEN None of the pins of the device triggered
THEN you receive no message
THEN 2nd device should receive 1 messages
* 00 55 11 11 | XX XX 09 01
THEN you can execute any other testcase, as the switch didnt crash
4) All MeyPins can be activated more than 15 minutes in parallel(Activate each port for at least 15 mins)
GIVE You have a relais connected to each of the ports
WHEN Send CAN Pkg 00 55 11 11 | XX XX 01 01 -> (MeyPin1 Should switch to on)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 02 01 -> (MeyPin2 Should switch to on)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 03 01 -> (MeyPin3 Should switch to on)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 04 01 -> (MeyPin4 Should switch to on)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 05 01 -> (MeyPin5 Should switch to on)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 06 01 -> (MeyPin6 Should switch to on)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 07 01 -> (MeyPin7 Should switch to on)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 08 01 -> (MeyPin8 Should switch to on)
THEN you should only receive the packages from above.
THEN you should NOT receive a VersionPackage
WHEN you wait 15 Minutes
THEN nothing should be send
Testfälle Meycan Switch
PreCons for each:
GIVEN XX XX is the deviceId of the target device
GIVEN YY YY is another device id, which is NOT XX XX
GIVEN 2nd CAN Debug Device on another CanBus of switch
1) A MeyPin can be triggered directly (repeat Test for all MeyPins and each CAN Bus Interface specified)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 01 01 -> (MeyPin1 Should switch to on)
THEN The MeyPin 1 should trigger
THEN you receive a message 00 50 XX XX | 01 01
THEN 2nd device should receive 2 messages
* 00 50 XX XX | 01 01
* 00 55 11 11 | XX XX 01 01
1a) A MeyPin trigger is effecltess, if only set
GIVEN the above testcast
WHEN Send CAN Pkg 00 55 11 11 | XX XX 01 01
THEN Nothing changed
THEN you dont receive a message
THEN 2nd device should receive 00 55 11 11 | XX XX 01 01
WHEN Send CAN Pkg 00 55 11 11 | XX XX 01 00 -> (MeyPin1 Should switch to off)
THEN The MeyPin 1 should switch to OFF
THEN you receive a message 00 50 XX XX | 01 00
THEN 2nd device should receive 2 messages
* 00 50 XX XX | 01 00
* 00 55 11 11 | XX XX 01 00
2) A MeyPin is not triggered, if the device id dont match
WHEN Send CAN Pkg 00 55 11 11 | YY YY 01 01
THEN None of the pins of the device triggered
THEN you receive no message
THEN 2nd device should receive 1 messages
* 00 55 11 11 | XX XX 01 01
3) A MeyPin is not triggered, if the Package Type dont match
WHEN Send CAN Pkg 50 00 11 11 | YY YY 01 01
THEN None of the pins of the device triggered
THEN you receive no message
THEN 2nd device should receive 1 messages
* 50 00 11 11 | XX XX 01 01
3) A MeyPin is not triggered, if the MeyPin is above 8 (max pins)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 09 01
THEN None of the pins of the device triggered
THEN you receive no message
THEN 2nd device should receive 1 messages
* 00 55 11 11 | XX XX 09 01
THEN you can execute any other testcase, as the switch didnt crash
4) All MeyPins can be activated more than 15 minutes in parallel(Activate each port for at least 15 mins)
GIVE You have a relais connected to each of the ports
WHEN Send CAN Pkg 00 55 11 11 | XX XX 01 01 -> (MeyPin1 Should switch to on)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 02 01 -> (MeyPin2 Should switch to on)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 03 01 -> (MeyPin3 Should switch to on)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 04 01 -> (MeyPin4 Should switch to on)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 05 01 -> (MeyPin5 Should switch to on)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 06 01 -> (MeyPin6 Should switch to on)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 07 01 -> (MeyPin7 Should switch to on)
WHEN Send CAN Pkg 00 55 11 11 | XX XX 08 01 -> (MeyPin8 Should switch to on)
THEN you should only receive the packages from above.
THEN you should NOT receive a VersionPackage
WHEN you wait 15 Minutes
THEN nothing should be send
THEN the Pins should not trigger

View File

@@ -0,0 +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"
}

View File

@@ -0,0 +1,540 @@
{
"version": 4,
"configurations": [
{
"name": "Arduino",
"compilerPath": "C:\\Users\\Martin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7\\bin\\avr-g++",
"compilerArgs": [
"-w",
"-std=gnu++17",
"-fpermissive",
"-fno-exceptions",
"-ffunction-sections",
"-fdata-sections",
"-fno-threadsafe-statics",
"-Wno-error=narrowing"
],
"intelliSenseMode": "gcc-x64",
"includePath": [
"C:\\Users\\Martin\\AppData\\Local\\Arduino15\\packages\\MegaCoreX\\hardware\\megaavr\\1.1.0\\cores\\coreX-corefiles\\api\\deprecated",
"C:\\Users\\Martin\\AppData\\Local\\Arduino15\\packages\\MegaCoreX\\hardware\\megaavr\\1.1.0\\cores\\coreX-corefiles",
"C:\\Users\\Martin\\AppData\\Local\\Arduino15\\packages\\MegaCoreX\\hardware\\megaavr\\1.1.0\\variants\\48pin-standard",
"C:\\Users\\Martin\\AppData\\Local\\Arduino15\\packages\\MegaCoreX\\hardware\\megaavr\\1.1.0\\libraries\\SPI\\src",
"C:\\Users\\Martin\\Documents\\Arduino\\libraries\\autowp-mcp2515",
"c:\\users\\martin\\appdata\\local\\arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7\\lib\\gcc\\avr\\7.3.0\\include",
"c:\\users\\martin\\appdata\\local\\arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7\\lib\\gcc\\avr\\7.3.0\\include-fixed",
"c:\\users\\martin\\appdata\\local\\arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7\\avr\\include"
],
"forcedInclude": [
"C:\\Users\\Martin\\AppData\\Local\\Arduino15\\packages\\MegaCoreX\\hardware\\megaavr\\1.1.0\\cores\\coreX-corefiles\\Arduino.h"
],
"cStandard": "c11",
"cppStandard": "c++17",
"defines": [
"F_CPU=8000000L",
"ARDUINO=10607",
"ARDUINO_AVR_ATmega809",
"ARDUINO_ARCH_MEGAAVR",
"__DBL_MIN_EXP__=(-125)",
"__HQ_FBIT__=15",
"__cpp_attributes=200809",
"__UINT_LEAST16_MAX__=0xffffU",
"__ATOMIC_ACQUIRE=2",
"__SFRACT_IBIT__=0",
"__FLT_MIN__=1.17549435e-38F",
"__GCC_IEC_559_COMPLEX=0",
"__BUILTIN_AVR_SLEEP=1",
"__BUILTIN_AVR_COUNTLSULLK=1",
"__cpp_aggregate_nsdmi=201304",
"__BUILTIN_AVR_COUNTLSULLR=1",
"__UFRACT_MAX__=0XFFFFP-16UR",
"__UINT_LEAST8_TYPE__=unsigned char",
"__DQ_FBIT__=63",
"__INTMAX_C(c)=c ## LL",
"__ULFRACT_FBIT__=32",
"__SACCUM_EPSILON__=0x1P-7HK",
"__CHAR_BIT__=8",
"__USQ_IBIT__=0",
"__UINT8_MAX__=0xff",
"__ACCUM_FBIT__=15",
"__WINT_MAX__=0x7fff",
"__FLT32_MIN_EXP__=(-125)",
"__cpp_static_assert=200410",
"__USFRACT_FBIT__=8",
"__ORDER_LITTLE_ENDIAN__=1234",
"__SIZE_MAX__=0xffffU",
"__WCHAR_MAX__=0x7fff",
"__LACCUM_IBIT__=32",
"__DBL_DENORM_MIN__=double(1.40129846e-45L)",
"__GCC_ATOMIC_CHAR_LOCK_FREE=1",
"__GCC_IEC_559=0",
"__FLT_EVAL_METHOD__=0",
"__BUILTIN_AVR_LLKBITS=1",
"__cpp_binary_literals=201304",
"__LLACCUM_MAX__=0X7FFFFFFFFFFFFFFFP-47LLK",
"__GCC_ATOMIC_CHAR32_T_LOCK_FREE=1",
"__BUILTIN_AVR_HKBITS=1",
"__BUILTIN_AVR_BITSLLK=1",
"__FRACT_FBIT__=15",
"__BUILTIN_AVR_BITSLLR=1",
"__cpp_variadic_templates=200704",
"__UINT_FAST64_MAX__=0xffffffffffffffffULL",
"__SIG_ATOMIC_TYPE__=char",
"__BUILTIN_AVR_UHKBITS=1",
"__UACCUM_FBIT__=16",
"__DBL_MIN_10_EXP__=(-37)",
"__FINITE_MATH_ONLY__=0",
"__cpp_variable_templates=201304",
"__LFRACT_IBIT__=0",
"__GNUC_PATCHLEVEL__=0",
"__FLT32_HAS_DENORM__=1",
"__LFRACT_MAX__=0X7FFFFFFFP-31LR",
"__UINT_FAST8_MAX__=0xff",
"__has_include(STR)=__has_include__(STR)",
"__DEC64_MAX_EXP__=385",
"__INT8_C(c)=c",
"__INT_LEAST8_WIDTH__=8",
"__UINT_LEAST64_MAX__=0xffffffffffffffffULL",
"__SA_FBIT__=15",
"__SHRT_MAX__=0x7fff",
"__LDBL_MAX__=3.40282347e+38L",
"__FRACT_MAX__=0X7FFFP-15R",
"__UFRACT_FBIT__=16",
"__UFRACT_MIN__=0.0UR",
"__UINT_LEAST8_MAX__=0xff",
"__GCC_ATOMIC_BOOL_LOCK_FREE=1",
"__UINTMAX_TYPE__=long long unsigned int",
"__LLFRACT_EPSILON__=0x1P-63LLR",
"__BUILTIN_AVR_DELAY_CYCLES=1",
"__DEC32_EPSILON__=1E-6DF",
"__FLT_EVAL_METHOD_TS_18661_3__=0",
"__UINT32_MAX__=0xffffffffUL",
"__GXX_EXPERIMENTAL_CXX0X__=1",
"__ULFRACT_MAX__=0XFFFFFFFFP-32ULR",
"__TA_IBIT__=16",
"__LDBL_MAX_EXP__=128",
"__WINT_MIN__=(-__WINT_MAX__ - 1)",
"__INT_LEAST16_WIDTH__=16",
"__ULLFRACT_MIN__=0.0ULLR",
"__SCHAR_MAX__=0x7f",
"__WCHAR_MIN__=(-__WCHAR_MAX__ - 1)",
"__INT64_C(c)=c ## LL",
"__DBL_DIG__=6",
"__GCC_ATOMIC_POINTER_LOCK_FREE=1",
"__AVR_HAVE_SPH__=1",
"__LLACCUM_MIN__=(-0X1P15LLK-0X1P15LLK)",
"__BUILTIN_AVR_KBITS=1",
"__BUILTIN_AVR_ABSK=1",
"__BUILTIN_AVR_ABSR=1",
"__SIZEOF_INT__=2",
"__SIZEOF_POINTER__=2",
"__GCC_ATOMIC_CHAR16_T_LOCK_FREE=1",
"__USACCUM_IBIT__=8",
"__USER_LABEL_PREFIX__",
"__STDC_HOSTED__=1",
"__LDBL_HAS_INFINITY__=1",
"__LFRACT_MIN__=(-0.5LR-0.5LR)",
"__HA_IBIT__=8",
"__FLT32_DIG__=6",
"__TQ_IBIT__=0",
"__FLT_EPSILON__=1.19209290e-7F",
"__GXX_WEAK__=1",
"__SHRT_WIDTH__=16",
"__USFRACT_IBIT__=0",
"__LDBL_MIN__=1.17549435e-38L",
"__FRACT_MIN__=(-0.5R-0.5R)",
"__AVR_SFR_OFFSET__=0x20",
"__DEC32_MAX__=9.999999E96DF",
"__cpp_threadsafe_static_init=200806",
"__DA_IBIT__=32",
"__INT32_MAX__=0x7fffffffL",
"__UQQ_FBIT__=8",
"__INT_WIDTH__=16",
"__SIZEOF_LONG__=4",
"__UACCUM_MAX__=0XFFFFFFFFP-16UK",
"__UINT16_C(c)=c ## U",
"__PTRDIFF_WIDTH__=16",
"__DECIMAL_DIG__=9",
"__LFRACT_EPSILON__=0x1P-31LR",
"__AVR_2_BYTE_PC__=1",
"__ULFRACT_MIN__=0.0ULR",
"__INTMAX_WIDTH__=64",
"__has_include_next(STR)=__has_include_next__(STR)",
"__BUILTIN_AVR_ULLRBITS=1",
"__LDBL_HAS_QUIET_NAN__=1",
"__ULACCUM_IBIT__=32",
"__UACCUM_EPSILON__=0x1P-16UK",
"__BUILTIN_AVR_SEI=1",
"__GNUC__=7",
"__ULLACCUM_MAX__=0XFFFFFFFFFFFFFFFFP-48ULLK",
"__cpp_delegating_constructors=200604",
"__HQ_IBIT__=0",
"__BUILTIN_AVR_SWAP=1",
"__FLT_HAS_DENORM__=1",
"__SIZEOF_LONG_DOUBLE__=4",
"__BIGGEST_ALIGNMENT__=1",
"__STDC_UTF_16__=1",
"__UINT24_MAX__=16777215UL",
"__BUILTIN_AVR_NOP=1",
"__GNUC_STDC_INLINE__=1",
"__DQ_IBIT__=0",
"__FLT32_HAS_INFINITY__=1",
"__DBL_MAX__=double(3.40282347e+38L)",
"__ULFRACT_IBIT__=0",
"__cpp_raw_strings=200710",
"__INT_FAST32_MAX__=0x7fffffffL",
"__DBL_HAS_INFINITY__=1",
"__INT64_MAX__=0x7fffffffffffffffLL",
"__ACCUM_IBIT__=16",
"__DEC32_MIN_EXP__=(-94)",
"__BUILTIN_AVR_UKBITS=1",
"__INTPTR_WIDTH__=16",
"__BUILTIN_AVR_FMULSU=1",
"__LACCUM_MAX__=0X7FFFFFFFFFFFFFFFP-31LK",
"__INT_FAST16_TYPE__=int",
"__LDBL_HAS_DENORM__=1",
"__BUILTIN_AVR_BITSK=1",
"__BUILTIN_AVR_BITSR=1",
"__cplusplus=201402L",
"__cpp_ref_qualifiers=200710",
"__DEC128_MAX__=9.999999999999999999999999999999999E6144DL",
"__INT_LEAST32_MAX__=0x7fffffffL",
"__USING_SJLJ_EXCEPTIONS__=1",
"__DEC32_MIN__=1E-95DF",
"__ACCUM_MAX__=0X7FFFFFFFP-15K",
"__DEPRECATED=1",
"__cpp_rvalue_references=200610",
"__DBL_MAX_EXP__=128",
"__USACCUM_EPSILON__=0x1P-8UHK",
"__WCHAR_WIDTH__=16",
"__FLT32_MAX__=3.40282347e+38F32",
"__DEC128_EPSILON__=1E-33DL",
"__SFRACT_MAX__=0X7FP-7HR",
"__FRACT_IBIT__=0",
"__PTRDIFF_MAX__=0x7fff",
"__UACCUM_MIN__=0.0UK",
"__UACCUM_IBIT__=16",
"__BUILTIN_AVR_NOPS=1",
"__BUILTIN_AVR_WDR=1",
"__FLT32_HAS_QUIET_NAN__=1",
"__GNUG__=7",
"__LONG_LONG_MAX__=0x7fffffffffffffffLL",
"__SIZEOF_SIZE_T__=2",
"__ULACCUM_MAX__=0XFFFFFFFFFFFFFFFFP-32ULK",
"__cpp_rvalue_reference=200610",
"__cpp_nsdmi=200809",
"__SIZEOF_WINT_T__=2",
"__LONG_LONG_WIDTH__=64",
"__cpp_initializer_lists=200806",
"__FLT32_MAX_EXP__=128",
"__SA_IBIT__=16",
"__ULLACCUM_MIN__=0.0ULLK",
"__BUILTIN_AVR_ROUNDUHK=1",
"__BUILTIN_AVR_ROUNDUHR=1",
"__cpp_hex_float=201603",
"__GXX_ABI_VERSION=1011",
"__INT24_MAX__=8388607L",
"__UTA_FBIT__=48",
"__FLT_MIN_EXP__=(-125)",
"__USFRACT_MAX__=0XFFP-8UHR",
"__UFRACT_IBIT__=0",
"__BUILTIN_AVR_ROUNDFX=1",
"__BUILTIN_AVR_ROUNDULK=1",
"__BUILTIN_AVR_ROUNDULR=1",
"__cpp_lambdas=200907",
"__BUILTIN_AVR_COUNTLSLLK=1",
"__BUILTIN_AVR_COUNTLSLLR=1",
"__BUILTIN_AVR_ROUNDHK=1",
"__INT_FAST64_TYPE__=long long int",
"__BUILTIN_AVR_ROUNDHR=1",
"__DBL_MIN__=double(1.17549435e-38L)",
"__BUILTIN_AVR_COUNTLSK=1",
"__BUILTIN_AVR_ROUNDLK=1",
"__BUILTIN_AVR_COUNTLSR=1",
"__BUILTIN_AVR_ROUNDLR=1",
"__LACCUM_MIN__=(-0X1P31LK-0X1P31LK)",
"__ULLACCUM_FBIT__=48",
"__BUILTIN_AVR_LKBITS=1",
"__ULLFRACT_EPSILON__=0x1P-64ULLR",
"__DEC128_MIN__=1E-6143DL",
"__REGISTER_PREFIX__",
"__UINT16_MAX__=0xffffU",
"__DBL_HAS_DENORM__=1",
"__BUILTIN_AVR_ULKBITS=1",
"__ACCUM_MIN__=(-0X1P15K-0X1P15K)",
"__AVR_ARCH__=2",
"__SQ_IBIT__=0",
"__FLT32_MIN__=1.17549435e-38F32",
"__UINT8_TYPE__=unsigned char",
"__BUILTIN_AVR_ROUNDUK=1",
"__BUILTIN_AVR_ROUNDUR=1",
"__UHA_FBIT__=8",
"__NO_INLINE__=1",
"__SFRACT_MIN__=(-0.5HR-0.5HR)",
"__UTQ_FBIT__=128",
"__FLT_MANT_DIG__=24",
"__LDBL_DECIMAL_DIG__=9",
"__VERSION__=\"7.3.0\"",
"__UINT64_C(c)=c ## ULL",
"__ULLFRACT_FBIT__=64",
"__cpp_unicode_characters=200704",
"__FRACT_EPSILON__=0x1P-15R",
"__ULACCUM_MIN__=0.0ULK",
"__UDA_FBIT__=32",
"__cpp_decltype_auto=201304",
"__LLACCUM_EPSILON__=0x1P-47LLK",
"__GCC_ATOMIC_INT_LOCK_FREE=1",
"__FLT32_MANT_DIG__=24",
"__BUILTIN_AVR_BITSUHK=1",
"__BUILTIN_AVR_BITSUHR=1",
"__FLOAT_WORD_ORDER__=__ORDER_LITTLE_ENDIAN__",
"__USFRACT_MIN__=0.0UHR",
"__BUILTIN_AVR_BITSULK=1",
"__ULLACCUM_IBIT__=16",
"__BUILTIN_AVR_BITSULR=1",
"__UQQ_IBIT__=0",
"__BUILTIN_AVR_LLRBITS=1",
"__SCHAR_WIDTH__=8",
"__BUILTIN_AVR_BITSULLK=1",
"__BUILTIN_AVR_BITSULLR=1",
"__INT32_C(c)=c ## L",
"__DEC64_EPSILON__=1E-15DD",
"__ORDER_PDP_ENDIAN__=3412",
"__DEC128_MIN_EXP__=(-6142)",
"__UHQ_FBIT__=16",
"__LLACCUM_FBIT__=47",
"__FLT32_MAX_10_EXP__=38",
"__BUILTIN_AVR_ROUNDULLK=1",
"__BUILTIN_AVR_ROUNDULLR=1",
"__INT_FAST32_TYPE__=long int",
"__BUILTIN_AVR_HRBITS=1",
"__UINT_LEAST16_TYPE__=unsigned int",
"__BUILTIN_AVR_UHRBITS=1",
"__INT16_MAX__=0x7fff",
"__SIZE_TYPE__=unsigned int",
"__UINT64_MAX__=0xffffffffffffffffULL",
"__UDQ_FBIT__=64",
"__INT8_TYPE__=signed char",
"__cpp_digit_separators=201309",
"__ELF__=1",
"__ULFRACT_EPSILON__=0x1P-32ULR",
"__LLFRACT_FBIT__=63",
"__FLT_RADIX__=2",
"__INT_LEAST16_TYPE__=int",
"__BUILTIN_AVR_ABSFX=1",
"__LDBL_EPSILON__=1.19209290e-7L",
"__UINTMAX_C(c)=c ## ULL",
"__INT24_MIN__=(-__INT24_MAX__-1)",
"__SACCUM_MAX__=0X7FFFP-7HK",
"__BUILTIN_AVR_ABSHR=1",
"__SIG_ATOMIC_MAX__=0x7f",
"__GCC_ATOMIC_WCHAR_T_LOCK_FREE=1",
"__cpp_sized_deallocation=201309",
"__SIZEOF_PTRDIFF_T__=2",
"__AVR=1",
"__BUILTIN_AVR_ABSLK=1",
"__BUILTIN_AVR_ABSLR=1",
"__LACCUM_EPSILON__=0x1P-31LK",
"__DEC32_SUBNORMAL_MIN__=0.000001E-95DF",
"__INT_FAST16_MAX__=0x7fff",
"__UINT_FAST32_MAX__=0xffffffffUL",
"__UINT_LEAST64_TYPE__=long long unsigned int",
"__USACCUM_MAX__=0XFFFFP-8UHK",
"__SFRACT_EPSILON__=0x1P-7HR",
"__FLT_HAS_QUIET_NAN__=1",
"__FLT_MAX_10_EXP__=38",
"__LONG_MAX__=0x7fffffffL",
"__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL",
"__FLT_HAS_INFINITY__=1",
"__cpp_unicode_literals=200710",
"__USA_FBIT__=16",
"__UINT_FAST16_TYPE__=unsigned int",
"__DEC64_MAX__=9.999999999999999E384DD",
"__INT_FAST32_WIDTH__=32",
"__BUILTIN_AVR_RBITS=1",
"__CHAR16_TYPE__=unsigned int",
"__PRAGMA_REDEFINE_EXTNAME=1",
"__SIZE_WIDTH__=16",
"__INT_LEAST16_MAX__=0x7fff",
"__DEC64_MANT_DIG__=16",
"__UINT_LEAST32_MAX__=0xffffffffUL",
"__SACCUM_FBIT__=7",
"__FLT32_DENORM_MIN__=1.40129846e-45F32",
"__GCC_ATOMIC_LONG_LOCK_FREE=1",
"__SIG_ATOMIC_WIDTH__=8",
"__INT_LEAST64_TYPE__=long long int",
"__INT16_TYPE__=int",
"__INT_LEAST8_TYPE__=signed char",
"__SQ_FBIT__=31",
"__DEC32_MAX_EXP__=97",
"__INT_FAST8_MAX__=0x7f",
"__INTPTR_MAX__=0x7fff",
"__QQ_FBIT__=7",
"__cpp_range_based_for=200907",
"__UTA_IBIT__=16",
"__AVR_ERRATA_SKIP__=1",
"__FLT32_MIN_10_EXP__=(-37)",
"__LDBL_MANT_DIG__=24",
"__SFRACT_FBIT__=7",
"__SACCUM_MIN__=(-0X1P7HK-0X1P7HK)",
"__DBL_HAS_QUIET_NAN__=1",
"__SIG_ATOMIC_MIN__=(-__SIG_ATOMIC_MAX__ - 1)",
"AVR=1",
"__BUILTIN_AVR_FMULS=1",
"__cpp_return_type_deduction=201304",
"__INTPTR_TYPE__=int",
"__UINT16_TYPE__=unsigned int",
"__WCHAR_TYPE__=int",
"__SIZEOF_FLOAT__=4",
"__AVR__=1",
"__BUILTIN_AVR_INSERT_BITS=1",
"__USQ_FBIT__=32",
"__UINTPTR_MAX__=0xffffU",
"__INT_FAST64_WIDTH__=64",
"__DEC64_MIN_EXP__=(-382)",
"__cpp_decltype=200707",
"__FLT32_DECIMAL_DIG__=9",
"__INT_FAST64_MAX__=0x7fffffffffffffffLL",
"__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1",
"__FLT_DIG__=6",
"__UINT_FAST64_TYPE__=long long unsigned int",
"__BUILTIN_AVR_BITSHK=1",
"__BUILTIN_AVR_BITSHR=1",
"__INT_MAX__=0x7fff",
"__LACCUM_FBIT__=31",
"__USACCUM_MIN__=0.0UHK",
"__UHA_IBIT__=8",
"__INT64_TYPE__=long long int",
"__BUILTIN_AVR_BITSLK=1",
"__BUILTIN_AVR_BITSLR=1",
"__FLT_MAX_EXP__=128",
"__UTQ_IBIT__=0",
"__DBL_MANT_DIG__=24",
"__cpp_inheriting_constructors=201511",
"__BUILTIN_AVR_ULLKBITS=1",
"__INT_LEAST64_MAX__=0x7fffffffffffffffLL",
"__DEC64_MIN__=1E-383DD",
"__WINT_TYPE__=int",
"__UINT_LEAST32_TYPE__=long unsigned int",
"__SIZEOF_SHORT__=2",
"__ULLFRACT_IBIT__=0",
"__LDBL_MIN_EXP__=(-125)",
"__UDA_IBIT__=32",
"__WINT_WIDTH__=16",
"__INT_LEAST8_MAX__=0x7f",
"__LFRACT_FBIT__=31",
"__LDBL_MAX_10_EXP__=38",
"__ATOMIC_RELAXED=0",
"__DBL_EPSILON__=double(1.19209290e-7L)",
"__BUILTIN_AVR_BITSUK=1",
"__BUILTIN_AVR_BITSUR=1",
"__UINT8_C(c)=c",
"__INT_LEAST32_TYPE__=long int",
"__BUILTIN_AVR_URBITS=1",
"__SIZEOF_WCHAR_T__=2",
"__LLFRACT_MAX__=0X7FFFFFFFFFFFFFFFP-63LLR",
"__TQ_FBIT__=127",
"__INT_FAST8_TYPE__=signed char",
"__ULLACCUM_EPSILON__=0x1P-48ULLK",
"__BUILTIN_AVR_ROUNDK=1",
"__BUILTIN_AVR_ROUNDR=1",
"__UHQ_IBIT__=0",
"__LLACCUM_IBIT__=16",
"__FLT32_EPSILON__=1.19209290e-7F32",
"__DBL_DECIMAL_DIG__=9",
"__STDC_UTF_32__=1",
"__INT_FAST8_WIDTH__=8",
"__DEC_EVAL_METHOD__=2",
"__TA_FBIT__=47",
"__UDQ_IBIT__=0",
"__ORDER_BIG_ENDIAN__=4321",
"__cpp_runtime_arrays=198712",
"__WITH_AVRLIBC__=1",
"__UINT64_TYPE__=long long unsigned int",
"__ACCUM_EPSILON__=0x1P-15K",
"__UINT32_C(c)=c ## UL",
"__BUILTIN_AVR_COUNTLSUHK=1",
"__INTMAX_MAX__=0x7fffffffffffffffLL",
"__cpp_alias_templates=200704",
"__BUILTIN_AVR_COUNTLSUHR=1",
"__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__",
"__FLT_DENORM_MIN__=1.40129846e-45F",
"__LLFRACT_IBIT__=0",
"__INT8_MAX__=0x7f",
"__LONG_WIDTH__=32",
"__UINT_FAST32_TYPE__=long unsigned int",
"__CHAR32_TYPE__=long unsigned int",
"__BUILTIN_AVR_COUNTLSULK=1",
"__BUILTIN_AVR_COUNTLSULR=1",
"__FLT_MAX__=3.40282347e+38F",
"__cpp_constexpr=201304",
"__USACCUM_FBIT__=8",
"__BUILTIN_AVR_COUNTLSFX=1",
"__INT32_TYPE__=long int",
"__SIZEOF_DOUBLE__=4",
"__FLT_MIN_10_EXP__=(-37)",
"__UFRACT_EPSILON__=0x1P-16UR",
"__INT_LEAST32_WIDTH__=32",
"__BUILTIN_AVR_COUNTLSHK=1",
"__BUILTIN_AVR_COUNTLSHR=1",
"__INTMAX_TYPE__=long long int",
"__BUILTIN_AVR_ABSLLK=1",
"__BUILTIN_AVR_ABSLLR=1",
"__DEC128_MAX_EXP__=6145",
"__AVR_HAVE_16BIT_SP__=1",
"__ATOMIC_CONSUME=1",
"__GNUC_MINOR__=3",
"__INT_FAST16_WIDTH__=16",
"__UINTMAX_MAX__=0xffffffffffffffffULL",
"__DEC32_MANT_DIG__=7",
"__HA_FBIT__=7",
"__BUILTIN_AVR_COUNTLSLK=1",
"__BUILTIN_AVR_COUNTLSLR=1",
"__BUILTIN_AVR_CLI=1",
"__DBL_MAX_10_EXP__=38",
"__LDBL_DENORM_MIN__=1.40129846e-45L",
"__INT16_C(c)=c",
"__cpp_generic_lambdas=201304",
"__STDC__=1",
"__PTRDIFF_TYPE__=int",
"__LLFRACT_MIN__=(-0.5LLR-0.5LLR)",
"__BUILTIN_AVR_LRBITS=1",
"__ATOMIC_SEQ_CST=5",
"__DA_FBIT__=31",
"__UINT32_TYPE__=long unsigned int",
"__BUILTIN_AVR_ROUNDLLK=1",
"__UINTPTR_TYPE__=unsigned int",
"__BUILTIN_AVR_ROUNDLLR=1",
"__USA_IBIT__=16",
"__BUILTIN_AVR_ULRBITS=1",
"__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD",
"__DEC128_MANT_DIG__=34",
"__LDBL_MIN_10_EXP__=(-37)",
"__BUILTIN_AVR_COUNTLSUK=1",
"__BUILTIN_AVR_COUNTLSUR=1",
"__SIZEOF_LONG_LONG__=8",
"__ULACCUM_EPSILON__=0x1P-32ULK",
"__cpp_user_defined_literals=200809",
"__SACCUM_IBIT__=8",
"__GCC_ATOMIC_LLONG_LOCK_FREE=1",
"__LDBL_DIG__=6",
"__FLT_DECIMAL_DIG__=9",
"__UINT_FAST16_MAX__=0xffffU",
"__GCC_ATOMIC_SHORT_LOCK_FREE=1",
"__BUILTIN_AVR_ABSHK=1",
"__BUILTIN_AVR_FLASH_SEGMENT=1",
"__INT_LEAST64_WIDTH__=64",
"__ULLFRACT_MAX__=0XFFFFFFFFFFFFFFFFP-64ULLR",
"__UINT_FAST8_TYPE__=unsigned char",
"__USFRACT_EPSILON__=0x1P-8UHR",
"__ULACCUM_FBIT__=32",
"__QQ_IBIT__=0",
"__cpp_init_captures=201304",
"__ATOMIC_ACQ_REL=4",
"__ATOMIC_RELEASE=3",
"__BUILTIN_AVR_FMUL=1",
"USBCON"
]
}
]
}

View File

@@ -0,0 +1,52 @@
#include <SPI.h>;
#include <mcp2515.h>;
struct can_frame frame;
MCP2515 mcp2515(10);
/*
Software matching Hardware of meycan v8.1
*/
void setup() {
SPI.begin();
Serial.begin(9600);
pinMode(PD3, OUTPUT);
digitalWrite(PD3, HIGH);
delay(1000);
digitalWrite(PD3, LOW);
delay(2000);
mcp2515.reset();
mcp2515.setBitrate(CAN_1000KBPS, MCP_8MHZ);
mcp2515.setNormalMode();
}
void loop() {
if (mcp2515.readMessage(&frame) == MCP2515::ERROR_OK) {
// frame contains received message
Serial.print(" Id: ");
Serial.print(frame.can_id, HEX);
Serial.print(" [");
for (int i = 0; i < 8; i++) {
Serial.print(frame.data[i], HEX);
Serial.print(" ");
}
Serial.println("]");
digitalWrite(PD3, HIGH);
delay(50);
digitalWrite(PD3, LOW);
delay(50);
mcp2515.sendMessage(&frame);
mcp2515.sendMessage(&frame);
mcp2515.sendMessage(&frame);
mcp2515.sendMessage(&frame);
}
}

View File

@@ -1,61 +1,45 @@
#include <iterator>
#include "esp32-hal-gpio.h"
#include "MeyCan.h";
#include <SPI.h>;
#include <mcp2515.h>;
#include "driver/twai.h"
PinState *MeyPin = NULL;
CanInterface *CanBusses = NULL;
uint16_t myDeviceId;
uint16_t myDeviceId = 0;
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->ForEach(handle);
}
void SetupMeyCan()
{
CalculateMyDeviceId();
if (MeyPin != NULL);
MeyPin->ForEach(SetupMeyPin);
if (CanBusses != NULL)
{
CanBusses->ForEach(InitCanInterface, NULL);
void SetupMeyPin(PinState *state) {
if (state->is_input) {
pinMode(state->pin_id, INPUT_PULLUP);
state->pin_state = digitalRead(state->pin_id);
} else {
pinMode(state->pin_id, OUTPUT);
digitalWrite(state->pin_id, LOW);
state->pin_state = true;
}
}
void SetCanInterface(byte index, byte pinId)
{
MCP2515* newCanInterface = new MCP2515(pinId);
CanInterface* canInterface = new CanInterface();
if (CanBusses == NULL)
CanBusses = canInterface;
else
CanBusses->AddCanInterface(canInterface);
void SetupMeyCan(byte majorHardwareVersion, byte minorHardwareVersion, byte deviceTypeId) {
_majorHardwareVersion = majorHardwareVersion;
_minorHardwareVersion = minorHardwareVersion;
_deviceTypeId = deviceTypeId;
if (MeyPin != NULL)
MeyPin->ForEach(SetupMeyPin);
}
void SetMeyPin(byte index, byte meyPinId, byte pinId)
{
PinState* newState = new PinState();
newState->Init(pinId, (byte) meyPinId);
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;
@@ -64,66 +48,69 @@ void SetMeyPin(byte index, byte meyPinId, byte pinId)
}
bool CheckPinStatus(PinState * state)
{
bool ReadPin(PinState *state) {
return digitalRead(state->pin_id);
}
void SendSwitchedTriggeredCanPackage(byte pinId, int state) {
twai_message_t message;
message.extd = 1;
message.rtr = 0;
message.ss = 0;
message.self = 0;
message.dlc_non_comp = 0;
message.identifier = CreateCanId(SWITCH_TRIGGERED_CAN_ID);
message.data_length_code = 2;
message.data[0] = pinId;
message.data[1] = state;
DoSendCanPkg(&message);
}
void CheckPinStatus(PinState *state) {
if (!state->is_input)
return false;
return;
bool newValue = ReadPin(state);
if (newValue != state->pin_state)
{
if (newValue != state->pin_state) {
delay(10);
newValue = ReadPin(state);
if (newValue != state->pin_state)
{
if (newValue != state->pin_state) {
state->pin_state = newValue;
SendSwitchedTriggeredCanPackage(state->meyPinId, state->pin_state);
}
}
return false;
return;
}
void CheckMeyPinsTriggered()
{
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);
uint16_t GetDeviceId(uint32_t canFrameId) {
return canFrameId & 0xFFFF;
}
void HandleFrame(can_frame *frame, MCP2515 *source)
{
CanBusses->ForEach(DoSendCanPkg, frame, source);
HandleTriggerMeypinCanPackage(frame);
uint16_t GetPackageType(uint32_t canFrameId) {
return (canFrameId / 0x10000) & 0xFFF;
}
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] ;
uint32_t CreateCanId(uint16_t commandId) {
return ((((uint32_t)commandId) & 0xFFF) * 0x10000) | myDeviceId;
}
void HandleTriggerMeypinCanPackage(twai_message_t *frame) {
if (GetPackageType(frame->identifier) == TRIGGER_SWITCH_CAN_ID) {
uint16_t adressedDeviceId = ((uint16_t)frame->data[0] << 8) | frame->data[1];
if (adressedDeviceId != myDeviceId) return;
@@ -132,10 +119,8 @@ void HandleTriggerMeypinCanPackage(can_frame *frame)
PinState *adressedPin = MeyPin->Find(meyPinId);
if (adressedPin != NULL)
{
if (adressedPin->is_input == true)
{
if (adressedPin != NULL) {
if (adressedPin->is_input == true) {
pinMode(adressedPin->pin_id, OUTPUT);
adressedPin->is_input = false;
}
@@ -147,104 +132,17 @@ void HandleTriggerMeypinCanPackage(can_frame *frame)
digitalWrite(adressedPin->pin_id, state);
SendSwitchedTriggeredCanPackage(adressedPin->meyPinId, state);
}
}
}
}
byte CircularShift(byte b)
{
return (b << 1) | (b >> 7 & 1);
void HandleFrame(twai_message_t *frame) {
HandleTriggerMeypinCanPackage(frame);
}
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 = 6;
toSend.data[0] = SOFTWARE_VERSION_HIGH;
toSend.data[1] = SOFTWARE_VERSION_LOW;
toSend.data[2] = HARDWARE_VERSION_HIGH;
toSend.data[3] = HARDWARE_VERSION_LOW;
toSend.data[4] = (myDeviceId >> 8) & 0xFF;
toSend.data[5] = myDeviceId & 0xFF;
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();
void DoSendCanPkg(twai_message_t *frame) {
esp_err_t ret = twai_transmit(frame, pdMS_TO_TICKS(1000));
}

View File

@@ -1,128 +1,80 @@
#ifndef MEYCAN_H
#define MEYCAN_H
#include <SPI.h>
#include <mcp2515.h>
typedef struct CanInterface
{
MCP2515 *interface;
CanInterface *next = NULL;
void ForEach(void (*handle)( MCP2515 *interface))
{
if (this->interface != NULL)
handle(this->interface);
if (this->next != NULL)
this->next->ForEach(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);
}
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 SetCanInterface(byte index, byte pinId);
void SetMeyPin(byte index, byte meyPinId, byte pinId);
void SetupMeyCan();
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 <Arduino.h>
#include <SPI.h>
#include "driver/twai.h"
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 = 6;
const byte SOFTWARE_VERSION_LOW = 0;
const byte HARDWARE_VERSION_HIGH = 8;
const byte HARDWARE_VERSION_LOW = 1;
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 SetupMeyCan(byte majorHardwareVersion, byte minorHardwareVersion, byte deviceTypeId);
uint32_t CreateCanId(uint16_t commandId);
void SetDevicedId(byte high, byte low);
void SetMeyPin(byte meyPinId, byte pinId);
uint16_t GetDeviceId(uint32_t canFrameId);
uint16_t GetPackageType(uint32_t canFrameId);
void SendSwitchedTriggeredCanPackage(byte pinId, int state);
void HandleFrame(twai_message_t *frame);
void CheckPinStatus(PinState *state);
void CheckMeyPinsTriggered(); /* checks weather a meypin triggered and sends a can pkg is neccessary */
void DoSendCanPkg(twai_message_t *frame) ;
#endif

View File

@@ -1,32 +1,82 @@
#include <SPI.h>;
#include <mcp2515.h>;
#include "MeyCan.h";
void setup() {
return;
SPI.begin();
_PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL.MCLKCTRLA | 1 << 7);
delay(10); // a bit delay for mcp2515 to get the clock
SetMeyPin(0, 1, PIN_PD0);
SetMeyPin(1, 2, PIN_PC7);
SetMeyPin(2, 3, PIN_PD2);
SetMeyPin(3, 4, PIN_PD1);
SetMeyPin(4, 5, PIN_PD5);
SetMeyPin(5, 6, PIN_PD3);
SetMeyPin(6, 7, PIN_PD7);
SetMeyPin(7, 8, PIN_PD6);
delay(20);
SetCanInterface(0, PIN_PD4);
SetupMeyCan();
}
void loop()
{
CheckMeyPinsTriggered();
}
#include <Arduino.h>
#include "driver/twai.h"
#include "MeyCan.h"
// https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/TWAI/TWAIreceive/TWAIreceive.ino
#define RX_PIN 2
#define TX_PIN 3
void DebugBlink(int d) {
pinMode(20, OUTPUT);
while (true) {
digitalWrite(20, HIGH);
delay(d);
digitalWrite(20, LOW);
delay(d);
}
}
bool driver_installed = false;
void setup() {
Serial.begin(9600);
SPI.begin();
// Explicit GND for LED and Input
pinMode(21, OUTPUT);
digitalWrite(21, LOW);
// Initialize configuration structures using macro initializers
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)TX_PIN, (gpio_num_t)RX_PIN, TWAI_MODE_NORMAL);
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_1MBITS(); //Look in the api-reference for other speed sets.
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
Serial.println("Driver installed");
} else {
DebugBlink(100);
return;
}
esp_err_t e = twai_start();
// Start TWAI driver
if (e == ESP_OK) {
driver_installed = true;
} else {
DebugBlink(500);
return;
}
SetDevicedId(0x05, 0x1F);
SetMeyPin(1, 5);
SetMeyPin(2, 6);
SetMeyPin(3, 7);
SetMeyPin(4, 8);
SetMeyPin(5, 9);
SetMeyPin(6, 10);
SetMeyPin(7, 20);
SetupMeyCan(8, 1, 3);
}
twai_message_t frame;
void loop() {
if (!driver_installed) {
// Driver not installed
DebugBlink(2000);
return;
}
CheckMeyPinsTriggered();
if (twai_receive(&frame, 0) == ESP_OK) {
HandleFrame(&frame);
}
}