CAN DUE, relative items, CAN-MQTT brige

This commit is contained in:
2024-03-30 08:29:53 +03:00
parent 242db1552e
commit 4fff338482
7 changed files with 128 additions and 48 deletions

View File

@@ -8,7 +8,7 @@
#if defined(ARDUINO_ARCH_STM32) #if defined(ARDUINO_ARCH_STM32)
#include <STM32_CAN.h> #include <STM32_CAN.h>
STM32_CAN STMCan( CAN1, ALT, RX_SIZE_64, TX_SIZE_16 ); STM32_CAN STMCan( CAN1, CAN_PINS::DEF, RX_SIZE_64, TX_SIZE_16 );
#endif #endif
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
@@ -24,6 +24,7 @@ extern systemConfig sysConf;
extern canStream CANConfStream; extern canStream CANConfStream;
extern aJsonObject * root; extern aJsonObject * root;
extern volatile int8_t configLocked; extern volatile int8_t configLocked;
extern bool configLoaded;
void printFrame(datagram_t * frame, uint8_t len ) { void printFrame(datagram_t * frame, uint8_t len ) {
@@ -163,6 +164,13 @@ bool canDriver::begin()
#if defined(__SAM3X8E__) #if defined(__SAM3X8E__)
Can0.begin(CAN_BPS_125K); Can0.begin(CAN_BPS_125K);
int filter;
//extended
for (filter = 0; filter < 3; filter++) {
Can0.setRXFilter(filter, 0, 0, true);
//Can1.setRXFilter(filter, 0, 0, true);
}
#endif #endif
debugSerial<<"CAN initialized"<<endl; debugSerial<<"CAN initialized"<<endl;
@@ -232,10 +240,15 @@ int canDriver::readFrame()
//DUE //DUE
#if defined(__SAM3X8E__) #if defined(__SAM3X8E__)
CAN_FRAME incoming; CAN_FRAME CAN_RX_msg;
if (Can0.available() > 0) { if (Can0.available() > 0) {
Can0.read(incoming);
printFrame(incoming); Can0.read(CAN_RX_msg);
if (CAN_RX_msg.length>8) CAN_RX_msg.length=8;
memcpy(RXpacket.data, CAN_RX_msg.data.bytes,CAN_RX_msg.length);
RXlen = CAN_RX_msg.length;
RXid.id = CAN_RX_msg.id;
return RXlen;
} }
#endif #endif
@@ -263,8 +276,10 @@ switch (state)
break; break;
case canState::Error: case canState::Error:
if (isTimeOver(responseTimer,millis(),10000UL)) if (configLoaded) state=canState::ConfigLoaded;
lookupMAC(); else
if (isTimeOver(responseTimer,millis(),10000UL))
lookupMAC();
break; break;
case canState::ReadConfig: case canState::ReadConfig:
@@ -314,13 +329,51 @@ bool canDriver::processPacket(canid_t id, datagram_t *packet, uint8_t len, bool
{ {
debugSerial.print("CAN Received "); debugSerial.print("CAN Received ");
debugSerialPort.print(len); debugSerial.print(len);
debugSerialPort.print(" bytes id 0x"); debugSerial.print(" bytes id 0x");
debugSerialPort.println(id.id,HEX); debugSerial.print(id.id,HEX);
if (len) printFrame(packet,len); if (len) printFrame(packet,len);
if (id.status) if (id.status){
//Responces //Responces
//@ any state
switch (id.payloadType)
{
case payloadType::itemCommand:
{
if (len!=8) return false;
aJsonObject *confObj = findConfbyID(id.deviceId);
if (confObj)
{
debugSerial<<F("CAN: status received for dev ")<<id.deviceId<<endl;
//char * itemNName = findItemName(id.itemId);
aJsonObject *itemsObj = aJson.getObjectItem(confObj,"items");
if (!itemsObj) return false;;
Item it(id.itemId, itemsObj);
if (it.isValid())
{
itemCmd ic;
uint16_t flags = 0;
ic.cmd = packet->cmd;
ic.param = packet->param;
debugSerial<<F("CAN: item ")<<it.itemArr->name;
ic.debugOut();
if (ic.isCommand()) flags |= FLAG_COMMAND;
if (ic.isValue()) flags |= FLAG_PARAMETERS;
ic.saveItem(&it,flags);
it.SendStatusImmediate(ic,flags | FLAG_NOT_SEND_CAN);
return true;
}
}
}
break;
}
switch (state) switch (state)
{ {
case canState::MACLookup: case canState::MACLookup:
@@ -346,8 +399,19 @@ if (id.status)
case canState::Error: case canState::Error:
return false; return false;
} }
}
else //Requests else //Requests
{ {
/*
switch (id.payloadType)
{
case payloadType::itemCommand:
break;
case payloadType::sysCmd:
break;
}*/
if ((id.payloadType == payloadType::itemCommand) && (len ==8)) if ((id.payloadType == payloadType::itemCommand) && (len ==8))
{ {
Item it(id.itemId); Item it(id.itemId);
@@ -439,7 +503,7 @@ uint8_t canDriver::getIdByMac(macAddress mac)
memset(macStr,0,sizeof(macStr)); memset(macStr,0,sizeof(macStr));
for (byte i = 0; i < 6; i++) for (byte i = 0; i < 6; i++)
{ {
if (mac[i]<16) macStr[strptr++]='0'; // if (mac[i]<16) macStr[strptr++]='0';
SetBytes(&mac[i],1,&macStr[strptr]); SetBytes(&mac[i],1,&macStr[strptr]);
strptr+=2; strptr+=2;
@@ -494,16 +558,16 @@ bool canDriver::write(uint32_t msg_id, datagram_t * buf, uint8_t size)
#endif #endif
#if defined(__SAM3X8E__) #if defined(__SAM3X8E__)
CAN_FRAME outGoting; CAN_FRAME CAN_TX_msg;
outgoing.id = 0x400; CAN_TX_msg.id = msg_id;
outgoing.extended = true; CAN_TX_msg.extended = true;
outgoing.priority = 4; //0-15 lower is higher priority CAN_TX_msg.length=size;
//outgoing.priority = 4; //0-15 lower is higher priority
outgoing.data.s0 = 0xFEED; if (buf) for(uint8_t i=0;i<size; i++) CAN_TX_msg.data.bytes[i]=buf->data[i];
outgoing.data.byte[2] = 0xDD; res=Can0.sendFrame(CAN_TX_msg);
outgoing.data.byte[3] = 0x55; if (res) debugSerial<<("CAN Wrote ")<<size<<" bytes, id "<<_HEX(msg_id)<<endl;
outgoing.data.high = 0xDEADBEEF; else debugSerial.println("CAN Write error");
Can0.sendFrame(outgoing); return res;
#endif #endif
} }
@@ -519,8 +583,10 @@ bool canDriver::sendStatus(uint8_t itemNum, itemCmd cmd)
bool canDriver::sendCommand(aJsonObject * can,itemCmd cmd, bool status) bool canDriver::sendCommand(aJsonObject * can,itemCmd cmd, bool status)
{ {
debugSerial<<"CAN: sendCommand "; // debugSerial<<"CAN: ";
cmd.debugOut(); // if (status) debugSerial<<F("sendStatus ");
// else debugSerial<<F("sendCommand ");
// cmd.debugOut();
if (can && (can->type == aJson_Array)) if (can && (can->type == aJson_Array))
{ {
@@ -549,7 +615,7 @@ bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool st
packet.cmd = cmd.cmd; packet.cmd = cmd.cmd;
packet.param = cmd.param; packet.param = cmd.param;
debugSerial << ((status)?"CAN: Status":"CAN: Command"); debugSerial << ((status)?"CAN: send Status":"CAN: send Command");
debugSerial<<F(" for dev:item ")<<devID<<":"<<itemID<<" "; debugSerial<<F(" for dev:item ")<<devID<<":"<<itemID<<" ";
cmd.debugOut(); cmd.debugOut();

View File

@@ -93,7 +93,7 @@ typedef union {
enum canState enum canState
{ {
Unknown, stateUnknown,
MACLookup, MACLookup,
Idle, Idle,
StreamOpenedWrite, StreamOpenedWrite,
@@ -110,7 +110,7 @@ Error
class canDriver class canDriver
{ {
public: public:
canDriver(){ready=false; controllerId=0; responseTimer=0; state=canState::Unknown;}; canDriver(){ready=false; controllerId=0; responseTimer=0; state=canState::stateUnknown;};
uint8_t getMyId(); uint8_t getMyId();
bool sendStatus(uint8_t itemNum, itemCmd cmd); bool sendStatus(uint8_t itemNum, itemCmd cmd);
bool sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool status=false); bool sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd, bool status=false);
@@ -139,6 +139,11 @@ private:
CAN_message_t CAN_RX_msg; CAN_message_t CAN_RX_msg;
CAN_message_t CAN_TX_msg; CAN_message_t CAN_TX_msg;
#endif #endif
#if defined(__SAM3X8E__)
//CAN_FRAME CAN_RX_msg;
#endif
bool ready; bool ready;
@@ -156,7 +161,7 @@ extern aJsonObject * topics;
class canStream : public Stream class canStream : public Stream
{ {
public: public:
canStream(canDriver * _driver) : readPos(0),writePos(0),devId(0), pType(payloadType::unknown),state(canState::Unknown){driver=_driver; } canStream(canDriver * _driver) : readPos(0),writePos(0),devId(0), pType(payloadType::unknown),state(canState::stateUnknown){driver=_driver; }
int open(uint8_t controllerID, payloadType _pType, char _mode) int open(uint8_t controllerID, payloadType _pType, char _mode)
{ {
if (mode) close(); if (mode) close();
@@ -171,7 +176,7 @@ public:
{ {
if ((mode == 'w') && writePos) flush(); if ((mode == 'w') && writePos) flush();
mode = '\0'; mode = '\0';
state=canState::Unknown; state=canState::stateUnknown;
return 1; return 1;
} }

View File

@@ -141,8 +141,9 @@ int txt2subItem(char *payload) {
//const short defval[4] = {0, 0, 0, 0}; //Type,Arg,Val,Cmd //const short defval[4] = {0, 0, 0, 0}; //Type,Arg,Val,Cmd
Item::Item(aJsonObject *obj)//Constructor Item::Item(aJsonObject *obj, aJsonObject *_items)//Constructor
{ {
rootItems=_items;
itemArr = obj; itemArr = obj;
driver = NULL; driver = NULL;
*defaultSubItem = 0; *defaultSubItem = 0;
@@ -291,13 +292,14 @@ Item::~Item()
} }
} }
Item::Item(char *name) //Constructor Item::Item(char *name, aJsonObject *_items) //Constructor
{ {
char * pDefaultSubItem = defaultSubItem; char * pDefaultSubItem = defaultSubItem;
rootItems=_items;
driver = NULL; driver = NULL;
defaultSubItem[0] =0; defaultSubItem[0] =0;
defaultSuffixCode = 0; defaultSuffixCode = 0;
if (name && items) if (name && rootItems)
{ char* sub; { char* sub;
if (sub=strchr(name,'/')) if (sub=strchr(name,'/'))
{ {
@@ -306,7 +308,7 @@ Item::Item(char *name) //Constructor
for(i=0;(name[i] && (name[i]!='/') && (i<MQTT_SUBJECT_LENGTH));i++) for(i=0;(name[i] && (name[i]!='/') && (i<MQTT_SUBJECT_LENGTH));i++)
buf[i]=name[i]; buf[i]=name[i];
buf[i]=0; buf[i]=0;
itemArr = aJson.getObjectItem(items, buf); itemArr = aJson.getObjectItem(rootItems, buf);
sub++; sub++;
strncpy(defaultSubItem,sub,sizeof(defaultSubItem)-1); strncpy(defaultSubItem,sub,sizeof(defaultSubItem)-1);
defaultSuffixCode = retrieveCode (&pDefaultSubItem); defaultSuffixCode = retrieveCode (&pDefaultSubItem);
@@ -314,7 +316,7 @@ Item::Item(char *name) //Constructor
//debugSerial<<F("defaultSubItem: ")<<defaultSubItem<<F(" defaultSuffixCode:")<<defaultSuffixCode<<endl; //debugSerial<<F("defaultSubItem: ")<<defaultSubItem<<F(" defaultSuffixCode:")<<defaultSuffixCode<<endl;
} }
else else
itemArr = aJson.getObjectItem(items, name); itemArr = aJson.getObjectItem(rootItems, name);
} }
else itemArr = NULL; else itemArr = NULL;
Parse(); Parse();
@@ -341,20 +343,21 @@ uint8_t getCanNum(aJsonObject* verb)
return 0; return 0;
} }
Item::Item(uint16_t num) Item::Item(uint16_t num, aJsonObject *_items)
{ {
itemArr = NULL; itemArr = NULL;
itemArg = NULL; itemArg = NULL;
itemVal = NULL; itemVal = NULL;
itemExt = NULL; itemExt = NULL;
rootItems=_items;
driver = NULL; driver = NULL;
defaultSubItem[0] =0; defaultSubItem[0] =0;
defaultSuffixCode = 0; defaultSuffixCode = 0;
if (!items) return; if (!rootItems) return;
itemArr = items->child; itemArr = rootItems->child;
while (itemArr) while (itemArr)
{ {
if (getCanNum(itemArr->child) == num) if (getCanNum(itemArr->child) == num)
@@ -778,7 +781,7 @@ return 0;
// Recursive function with small stack consumption // Recursive function with small stack consumption
// if cmd defined - execute Ctrl for any group members recursively // if cmd defined - execute Ctrl for any group members recursively
// else performs Activity check for group members and return true if any member is active // else performs Activity check for group members and return true if any member is active
bool digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem, bool authorized) bool Item::digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem, bool authorized)
{ if (!itemArr || itemArr->type!=aJson_Array) return false; { if (!itemArr || itemArr->type!=aJson_Array) return false;
// Iterate across array of names // Iterate across array of names
aJsonObject *i = itemArr->child; aJsonObject *i = itemArr->child;
@@ -786,7 +789,7 @@ bool digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem, bool authorize
while (i) { while (i) {
if (i->type == aJson_String) if (i->type == aJson_String)
{ //debugSerial<< i->valuestring<<endl; { //debugSerial<< i->valuestring<<endl;
aJsonObject *nextItem = aJson.getObjectItem(items, i->valuestring); aJsonObject *nextItem = aJson.getObjectItem(rootItems, i->valuestring);
if (nextItem && nextItem->type == aJson_Array) //nextItem is correct item if (nextItem && nextItem->type == aJson_Array) //nextItem is correct item
{ {
Item it(nextItem); Item it(nextItem);
@@ -1789,7 +1792,7 @@ int Item::SendStatus(int sendFlags) {
st.debugOut(); st.debugOut();
#ifdef CANDRV #ifdef CANDRV
LHCAN.sendStatus(getCanNum(itemArr->child),st); if (!(sendFlags & FLAG_NOT_SEND_CAN)) LHCAN.sendStatus(getCanNum(itemArr->child),st);
#endif #endif
if (sendFlags & FLAG_COMMAND) if (sendFlags & FLAG_COMMAND)
@@ -2501,7 +2504,7 @@ int Item::checkModbusDimmer() {
nextItem.checkModbusDimmer(data); nextItem.checkModbusDimmer(data);
pollingItem = pollingItem->next; pollingItem = pollingItem->next;
if (!pollingItem) if (!pollingItem)
pollingItem = items->child; pollingItem = rootItems->child;
} }
} else } else
debugSerial << F("MB: polling ") << itemArr->name<< F(" error=") << _HEX(result) << endl; debugSerial << F("MB: polling ") << itemArr->name<< F(" error=") << _HEX(result) << endl;

View File

@@ -98,17 +98,17 @@ extern aJsonObject *items;
extern short thermoSetCurTemp(char *name, float t); extern short thermoSetCurTemp(char *name, float t);
int txt2cmd (char * payload); int txt2cmd (char * payload);
bool digGroup (aJsonObject *itemArr, itemCmd *cmd = NULL, char* subItem = NULL, bool authorized = false);
class Item class Item
{ {
public: public:
aJsonObject *itemArr, *itemArg,*itemVal,*itemExt; aJsonObject *rootItems, *itemArr, *itemArg,*itemVal,*itemExt;
uint8_t itemType; uint8_t itemType;
abstractOut * driver; abstractOut * driver;
Item(char * name); Item(char * name, aJsonObject *_items = items);
Item(aJsonObject * obj); Item(aJsonObject * obj, aJsonObject *_items = items);
Item(uint16_t num); Item(uint16_t num, aJsonObject *_items = items);
~Item(); ~Item();
boolean isValid (); boolean isValid ();
@@ -148,7 +148,9 @@ class Item
int scheduleOppositeCommand(itemCmd cmd,bool isActiveNow,bool authorized); int scheduleOppositeCommand(itemCmd cmd,bool isActiveNow,bool authorized);
int isScheduled(); int isScheduled();
protected: protected:
bool digGroup (aJsonObject *itemArr, itemCmd *cmd = NULL, char* subItem = NULL, bool authorized = false);
long int limitSetValue(); long int limitSetValue();
int VacomSetFan (itemCmd st); int VacomSetFan (itemCmd st);
int VacomSetHeat(itemCmd st); int VacomSetHeat(itemCmd st);

View File

@@ -119,7 +119,7 @@ const ch_type ch_type_P[] PROGMEM =
#define FLAG_HALTED 0x40000UL #define FLAG_HALTED 0x40000UL
#define FLAG_XON 0x80000UL #define FLAG_XON 0x80000UL
#define FLAG_NOT_SEND_CAN 0x2UL
int txt2cmd (char * payload); int txt2cmd (char * payload);

View File

@@ -766,7 +766,9 @@ switch (cmdType)
if (mqttClient.connected() && !ethernetIdleCount) if (mqttClient.connected() && !ethernetIdleCount)
{ {
if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring); if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring); ///ChangeMe - if no '/' in addr - template not working
debugSerial << F("MQTT: ")<<addrstr<< F(" -> ")<<emitCommand<<endl;
mqttClient.publish(addrstr, emitCommand , true); mqttClient.publish(addrstr, emitCommand , true);
} }
} // emit } // emit

View File

@@ -733,6 +733,8 @@ lib_deps =
https://github.com/khoih-prog/TimerInterrupt_Generic.git https://github.com/khoih-prog/TimerInterrupt_Generic.git
https://github.com/rlogiacco/CircularBuffer https://github.com/rlogiacco/CircularBuffer
rweather/Crypto rweather/Crypto
https://github.com/collin80/due_can.git
https://github.com/collin80/can_common.git
monitor_speed = 115200 monitor_speed = 115200
[env:controllino] [env:controllino]