diff --git a/arduino/common/lib/commsControl/commsConstants.h b/arduino/common/lib/commsControl/commsConstants.h index fecc66bb65ad8eef33c67451b73b19d63e5463b6..1d658631a47c9135e452bc5d18857ad758cec1b3 100644 --- a/arduino/common/lib/commsControl/commsConstants.h +++ b/arduino/common/lib/commsControl/commsConstants.h @@ -85,64 +85,67 @@ class payload { public: payload(payloadType type = payloadType::payloadUnset) {type_ = type; } //data_ = nullptr; cmd_ = nullptr; alarm_ = nullptr; } payload(const payload &other) { -// unsetAll(); type_ = other.type_; - /*if ( other. data_ != nullptr) { data_ = new dataFormat;*/ memcpy(& data_, & other.data_, sizeof( dataFormat));// } else { data_ = nullptr; } - /*if ( other. cmd_ != nullptr) { cmd_ = new cmdFormat;*/ memcpy(& cmd_, & other.cmd_, sizeof( cmdFormat));// } else { cmd_ = nullptr; } - /*if ( other.alarm_ != nullptr) { alarm_ = new alarmFormat;*/ memcpy(&alarm_, &other.alarm_, sizeof(alarmFormat));// } else {alarm_ = nullptr; } + memcpy(& data_, &other. data_, sizeof( dataFormat)); + memcpy(& cmd_, &other. cmd_, sizeof( cmdFormat)); + memcpy(&alarm_, &other.alarm_, sizeof(alarmFormat)); } payload& operator=(const payload& other) { -// unsetAll(); type_ = other.type_; - /*if ( other. data_ != nullptr) { data_ = new dataFormat;*/ memcpy(& data_, & other.data_, sizeof( dataFormat));// } else { data_ = nullptr; } - /*if ( other. cmd_ != nullptr) { cmd_ = new cmdFormat;*/ memcpy(& cmd_, & other.cmd_, sizeof( cmdFormat));// } else { cmd_ = nullptr; } - /*if ( other.alarm_ != nullptr) { alarm_ = new alarmFormat;*/ memcpy(&alarm_, &other.alarm_, sizeof(alarmFormat));// } else {alarm_ = nullptr; } - + memcpy(& data_, &other. data_, sizeof( dataFormat)); + memcpy(& cmd_, &other. cmd_, sizeof( cmdFormat)); + memcpy(&alarm_, &other.alarm_, sizeof(alarmFormat)); return *this; } - ~payload() {;}//unsetData(); unsetAlarm(); unsetCmd();} + ~payload() { unsetAll(); } void setType(payloadType type) { type_ = type; } payloadType getType() {return type_; } // requires argument as new struct - void setData (dataFormat *data) { /*unsetAll(); */ type_ = payloadType::payloadData; /* data_ = new dataFormat( *data); }*/ memcpy(& data_, data, sizeof( dataFormat)); } - void setCmd (cmdFormat *cmd) { /*unsetAll(); */ type_ = payloadType::payloadCmd; /* cmd_ = new cmdFormat( *cmd); }*/ memcpy(& cmd_, cmd, sizeof( cmdFormat)); } - void setAlarm(alarmFormat *alarm) { /*unsetAll(); */ type_ = payloadType::payloadAlarm;/* alarm_ = new alarmFormat( *alarm); }*/ memcpy(&alarm_, alarm, sizeof(alarmFormat)); } + void setData (dataFormat *data) { type_ = payloadType::payloadData; memcpy(& data_, data, sizeof( dataFormat)); } + void setCmd (cmdFormat *cmd) { type_ = payloadType::payloadCmd; memcpy(& cmd_, cmd, sizeof( cmdFormat)); } + void setAlarm(alarmFormat *alarm) { type_ = payloadType::payloadAlarm; memcpy(&alarm_, alarm, sizeof(alarmFormat)); } - dataFormat *getData () {return &data_; } - cmdFormat *getCmd () {return &cmd_; } + // get pointers to particular payload types + dataFormat *getData () {return & data_; } + cmdFormat *getCmd () {return & cmd_; } alarmFormat *getAlarm() {return &alarm_; } -// void unsetAll() { unsetData(); unsetAlarm(); unsetCmd(); type_ = payloadType::payloadUnset; } -// void unsetData() { if ( data_ != nullptr) { delete data_; data_ = nullptr; } } -// void unsetCmd() { if ( cmd_ != nullptr) { delete cmd_; cmd_ = nullptr; } } -// void unsetAlarm() { if (alarm_ != nullptr) { delete alarm_; alarm_ = nullptr; } } + void unsetAll() { unsetData(); unsetAlarm(); unsetCmd(); type_ = payloadType::payloadUnset; } + void unsetData() { memset(& data_, 0, sizeof( dataFormat)); } + void unsetCmd() { memset(& cmd_, 0, sizeof( cmdFormat)); } + void unsetAlarm() { memset(&alarm_, 0, sizeof(alarmFormat)); } + + void setPayload(payloadType type, void* information) { + setType(type); + setInformation(information); + } - void setPayload(payloadType type, void* dt) { - switch (type) { + void setInformation(void* information) { + switch (type_) { case payloadType::payloadData: - setData(reinterpret_cast<dataFormat*>(dt)); + setData (reinterpret_cast< dataFormat*>(information)); break; case payloadType::payloadCmd: - setCmd(reinterpret_cast<cmdFormat*>(dt)); + setCmd (reinterpret_cast< cmdFormat*>(information)); break; case payloadType::payloadAlarm: - setAlarm(reinterpret_cast<alarmFormat*>(dt)); + setAlarm(reinterpret_cast<alarmFormat*>(information)); break; default: break; } } - // returns void pointer, in case you know what to do with data + // returns void pointer, in case you know what to do with data or dont care what the format is void *getInformation() { switch (type_) { case payloadType::payloadData: - return reinterpret_cast<void*>(getData()); + return reinterpret_cast<void*>(getData ()); case payloadType::payloadCmd: - return reinterpret_cast<void*>(getCmd()); + return reinterpret_cast<void*>(getCmd ()); case payloadType::payloadAlarm: return reinterpret_cast<void*>(getAlarm()); default: @@ -150,7 +153,8 @@ public: } } - uint8_t getInformationSize() { + // returns payload information size + uint8_t getSize() { switch (type_) { case payloadType::payloadData: return static_cast<uint8_t>(sizeof( dataFormat)); diff --git a/arduino/common/lib/commsControl/commsControl.cpp b/arduino/common/lib/commsControl/commsControl.cpp index 00fb149b2bd61068aae7f5512401a63f60a3173e..69eb4cf4a3a23f2b84b381c1a91134e056d9c99e 100644 --- a/arduino/common/lib/commsControl/commsControl.cpp +++ b/arduino/common/lib/commsControl/commsControl.cpp @@ -99,13 +99,13 @@ void commsControl::receiver() { break; case COMMS_CONTROL_ACK: // received ACK - finishPacket(&type); + finishPacket(type); break; default: uint8_t tmpSequenceReceive = (control >> 1 ) & 0x7F; tmpSequenceReceive += 1; // received DATA - if (receivePacket(&type)) { + if (receivePacket(type)) { commsAck_->setAddress(commsTmp_.getAddress()); commsAck_->setSequenceReceive(tmpSequenceReceive); sendPacket(commsAck_); @@ -155,16 +155,16 @@ bool commsControl::writePayload(payload &pl) { return false; } - RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *tmpQueue = getQueue(&type); + RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *queue = getQueue(type); // add new entry to the queue - if (tmpQueue->isFull()) { + if (queue->isFull()) { commsFormat *tmpCommsRm; - if (tmpQueue->pop(tmpCommsRm)) { + if (queue->pop(tmpCommsRm)) { delete tmpCommsRm; } } - if (tmpQueue->push(tmpComms) ) { + if (queue->push(tmpComms) ) { return true; } return false; @@ -258,46 +258,28 @@ void commsControl::resendPacket(RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING // receiving anything of commsFormat -bool commsControl::receivePacket(payloadType *type) { - payload tmpPl = payload(*type); - - void *tmpInformation = nullptr; - switch (*type) { - case payloadType::payloadData: - tmpInformation = reinterpret_cast<void*>(tmpPl.getData()); -// tmpInformation = reinterpret_cast<void*>(new dataFormat); - break; - case payloadType::payloadCmd: - tmpInformation = reinterpret_cast<void*>(tmpPl.getCmd()); -// tmpInformation = reinterpret_cast<void*>(new cmdFormat); - break; - case payloadType::payloadAlarm: - tmpInformation = reinterpret_cast<void*>(tmpPl.getAlarm()); -// tmpInformation = reinterpret_cast<void*>(new alarmFormat); - break; - default: - break; - } - - if (tmpInformation == nullptr) { - return false; - } - memcpy(tmpInformation, commsTmp_.getInformation(), commsTmp_.getInfoSize()); - tmpPl.setPayload(*type, tmpInformation); - - // remove first entry if RB is full - if (queueReceived_->isFull()) { - payload tmpPlRm; - if (queueReceived_->pop(tmpPlRm)) { - ; +bool commsControl::receivePacket(payloadType &type) { + payloadTmp_.unsetAll(); + payloadTmp_.setType(type); + void *tmpInformation = payloadTmp_.getInformation(); + // if type is definet, copy information from comms to payload + if (tmpInformation != nullptr) { + memcpy(tmpInformation, commsTmp_.getInformation(), commsTmp_.getInfoSize()); + + // remove first entry if queue is full + if (queueReceived_->isFull()) { + payload tmpPlRm; + if (queueReceived_->pop(tmpPlRm)) { + ; + } } + return queueReceived_->push(payloadTmp_); } - - return queueReceived_->push(tmpPl); + return false; } // if FCS is ok, remove from queue -void commsControl::finishPacket(payloadType *type) { +void commsControl::finishPacket(payloadType &type) { RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *tmpQueue = getQueue(type); if (tmpQueue != nullptr && !tmpQueue->isEmpty()) { @@ -327,8 +309,8 @@ payloadType commsControl::getInfoType(uint8_t *address) { } // get link to queue according to packet format -RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *commsControl::getQueue(payloadType *type) { - switch (*type) { +RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *commsControl::getQueue(payloadType &type) { + switch (type) { case payloadType::payloadAlarm: return queueAlarm_; case payloadType::payloadCmd: diff --git a/arduino/common/lib/commsControl/commsControl.h b/arduino/common/lib/commsControl/commsControl.h index 789f360585a89a886a8a022e01a2faef831622f5..21dc3d556545f20898a9ceb26b9b976b7426997e 100644 --- a/arduino/common/lib/commsControl/commsControl.h +++ b/arduino/common/lib/commsControl/commsControl.h @@ -26,13 +26,13 @@ public: void receiver(); private: - RingBuf<commsFormat *,CONST_MAX_SIZE_RB_SENDING> *getQueue(payloadType *type); + RingBuf<commsFormat *,CONST_MAX_SIZE_RB_SENDING> *getQueue(payloadType &type); payloadType getInfoType(uint8_t *address); void sendQueue (RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *queue); void resendPacket (RingBuf<commsFormat *, CONST_MAX_SIZE_RB_SENDING> *queue); - bool receivePacket(payloadType *type); - void finishPacket (payloadType *type); + bool receivePacket(payloadType &type); + void finishPacket (payloadType &type); bool encoder(uint8_t* payload, uint8_t dataSize); bool decoder(uint8_t* payload, uint8_t dataStart, uint8_t dataStop); @@ -52,6 +52,7 @@ private: RingBuf<payload, CONST_MAX_SIZE_RB_RECEIVING> *queueReceived_; + payload payloadTmp_; commsFormat commsTmp_; uint32_t baudrate_; diff --git a/arduino/common/lib/commsControl/commsFormat.cpp b/arduino/common/lib/commsControl/commsFormat.cpp index b4951e597f8dc635810eb730d2d3f38bc7f38398..22bde48b2a33607dff2441c5dbc56674368511c8 100644 --- a/arduino/common/lib/commsControl/commsFormat.cpp +++ b/arduino/common/lib/commsControl/commsFormat.cpp @@ -94,17 +94,17 @@ void commsFormat::copyData(uint8_t* data, uint8_t dataSize) { // STATIC METHODS // TODO rewrite in a slightly better way using the enum commsFormat* commsFormat::generateALARM(payload *pl) { - commsFormat *tmpComms = new commsFormat(pl->getInformationSize(), PACKET_ALARM); + commsFormat *tmpComms = new commsFormat(pl->getSize(), PACKET_ALARM); tmpComms->setInformation(pl); return tmpComms; } commsFormat* commsFormat::generateCMD (payload *pl) { - commsFormat *tmpComms = new commsFormat(pl->getInformationSize(), PACKET_CMD ); + commsFormat *tmpComms = new commsFormat(pl->getSize(), PACKET_CMD ); tmpComms->setInformation(pl); return tmpComms; } commsFormat* commsFormat::generateDATA (payload *pl) { - commsFormat *tmpComms = new commsFormat(pl->getInformationSize(), PACKET_DATA ); + commsFormat *tmpComms = new commsFormat(pl->getSize(), PACKET_DATA ); tmpComms->setInformation(pl); return tmpComms; } diff --git a/arduino/protocol/platformio.ini b/arduino/protocol/platformio.ini index 46ff784048a7388b5f9d13e53b04d75b8f1d51de..62149f68ec704517da1308e246f87cf293a5c556 100644 --- a/arduino/protocol/platformio.ini +++ b/arduino/protocol/platformio.ini @@ -17,6 +17,7 @@ lib_deps = 5390 ; uCRC16Lib 5418 ; RingBuffer build_flags = -fpermissive -I../common/include/ +lib_extra_dirs = ../common/lib [env:uno] platform = atmelavr diff --git a/arduino/protocol/platformio.pro b/arduino/protocol/platformio.pro index 7aa95f3693275c245c73fbc05683720531233fa4..f85d56595ae90ff70d4bf7e1c6cdda9f488219fc 100644 --- a/arduino/protocol/platformio.pro +++ b/arduino/protocol/platformio.pro @@ -6,7 +6,7 @@ else { } INCLUDEPATH += "$${_PRO_FILE_PWD_}/include" INCLUDEPATH += "$${_PRO_FILE_PWD_}/src" -INCLUDEPATH += "$${_PRO_FILE_PWD_}/lib/commsControl" +INCLUDEPATH += "$${_PRO_FILE_PWD_}/../common/lib/commsControl" INCLUDEPATH += "$${_PRO_FILE_PWD_}/.pio/libdeps/uno/uCRC16Lib_ID5390/src" INCLUDEPATH += "$${_PRO_FILE_PWD_}/.pio/libdeps/uno/RingBuffer_ID5418/src" INCLUDEPATH += "$${HOMEDIR}/.platformio/packages/framework-arduino-avr/cores/arduino" @@ -31,9 +31,9 @@ DEFINES += "__AVR_ATmega328P__" OTHER_FILES += platformio.ini SOURCES += src/protocol.cpp \ - lib/commsControl/commsControl.cpp \ - lib/commsControl/commsFormat.cpp + ../common/lib/commsControl/commsControl.cpp \ + ../common/lib/commsControl/commsFormat.cpp -HEADERS += lib/commsControl/commsConstants.h \ - lib/commsControl/commsControl.h \ - lib/commsControl/commsFormat.h +HEADERS += ../common/lib/commsControl/commsConstants.h \ + ../common/lib/commsControl/commsControl.h \ + ../common/lib/commsControl/commsFormat.h diff --git a/arduino/protocol/src/protocol.cpp b/arduino/protocol/src/protocol.cpp index 3b94233029e10c58fa7698e42781c8af40e63a32..5bcb36863fd42ffdeaa6e2b6780167ab0c917a0f 100644 --- a/arduino/protocol/src/protocol.cpp +++ b/arduino/protocol/src/protocol.cpp @@ -21,6 +21,11 @@ bool blue_ = false; bool green_ = false; bool red_ = false; +bool enabled_ = false; + +uint32_t lastTime_ = 0; + +uint32_t offset_ = 10; // dirty function to switch one of the LEDs void switchLED(int led) { @@ -76,23 +81,40 @@ void loop() { } previousState_ = currentState_; } -// switchLED(LED_BLUE); - // counter increase on button press -// plSend_.getData()->fsm_state += 1; -// comms_.writePayload(plSend_); + + if (enabled_ & (millis() > (lastTime_ + offset_))) + { + lastTime_ = millis(); + + plSend_.getData()->readback_valve_air_in = static_cast<uint8_t>((lastTime_ >> 24) & 0xFF); + plSend_.getData()->readback_valve_o2_in = static_cast<uint8_t>((lastTime_ >> 16) & 0xFF); + plSend_.getData()->readback_valve_inhale = static_cast<uint8_t>((lastTime_ >> 8 ) & 0xFF); + plSend_.getData()->readback_valve_exhale = static_cast<uint8_t>((lastTime_ >> 0 ) & 0xFF); + + switchLED(LED_BLUE); + plSend_.setType(payloadType::payloadData); + plSend_.getData()->fsm_state += 1; + comms_.writePayload(plSend_); + } // per cycle sender comms_.sender(); // per cycle receiver comms_.receiver(); - // per cycle data checker - the received entry is automatically removed from the buffer if (comms_.readPayload(plReceive_)) { switch (plReceive_.getType()) { case payloadType::payloadCmd: - switchLED(plReceive_.getCmd()->cmdCode); - alarm_.alarmCode = plReceive_.getCmd()->cmdCode + 1; + if (plReceive_.getCmd()->cmdCode % 2 == 0) { + enabled_ = false; + } else { + enabled_ = true; + } + offset_ = plReceive_.getCmd()->param; + + alarm_.alarmCode = plReceive_.getCmd()->cmdCode; + alarm_.param = millis() & 0xFFFFFFFF; plSend_.setAlarm(&alarm_); comms_.writePayload(plSend_); break; @@ -102,5 +124,4 @@ void loop() { plReceive_.setType(payloadType::payloadUnset); } - delay(50); } diff --git a/raspberry-dataserver/commsConstants.py b/raspberry-dataserver/commsConstants.py index 0207a09704c0f9090abd85859213cd6a3a29b405..a5668a58b075273e19d79ea2d482ae4f52f3ff77 100644 --- a/raspberry-dataserver/commsConstants.py +++ b/raspberry-dataserver/commsConstants.py @@ -59,7 +59,7 @@ class dataFormat(BaseFormat): # < = little endian # > = big endian # ! = network format (big endian) - self._dataStruct = Struct("!BBHHHHHHHHHBBBBBB") + self._dataStruct = Struct("<BBHHHHHHHHHBBBBBB") self._byteArray = None self._type = payloadType.payloadData @@ -184,7 +184,7 @@ class dataFormat(BaseFormat): class commandFormat(BaseFormat): def __init__(self): super().__init__() - self._dataStruct = Struct("!BBI") + self._dataStruct = Struct("<BBI") self._byteArray = None self._type = payloadType.payloadCmd @@ -231,7 +231,7 @@ class command_codes(Enum): class alarmFormat(BaseFormat): def __init__(self): super().__init__() - self._dataStruct = Struct("!BBI") + self._dataStruct = Struct("<BBI") self._byteArray = None self._type = payloadType.payloadAlarm diff --git a/raspberry-dataserver/commsControl.py b/raspberry-dataserver/commsControl.py index 4ba141f2e9322c05c1eaeeb2a2c343a9365cc75f..3c929352bfa497e68968688550aec603b5900542 100644 --- a/raspberry-dataserver/commsControl.py +++ b/raspberry-dataserver/commsControl.py @@ -15,7 +15,7 @@ from collections import deque import binascii import logging -logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') # communication class that governs talking between devices @@ -44,21 +44,19 @@ class commsControl(): self._sequenceReceive = 0 # initialize of the multithreading - self._lock = threading.Lock() + self._lockSerial = threading.Lock() self._receiving = True - receivingWorker = threading.Thread(target=self.receiver, daemon=True) - receivingWorker.start() + threading.Thread(target=self.receiver, daemon=True).start() self._sending = True self._datavalid = threading.Event() # callback for send process self._dvlock = threading.Lock() # make callback threadsafe - sendingWorker = threading.Thread(target=self.sender, daemon=True) - sendingWorker.start() + threading.Thread(target=self.sender, daemon=True).start() # open serial port def openSerial(self, port, baudrate = 115200, timeout = 2): if port is not None: - self._serial = serial.Serial(port = port, baudrate=baudrate, timeout = timeout) + self._serial = serial.Serial(port = port, baudrate=baudrate, timeout = timeout, dsrdtr = True) else: try: self._serial.close() @@ -74,14 +72,21 @@ class commsControl(): self.sendQueue(self._alarms , 10) self.sendQueue(self._commands, 50) self.sendQueue(self._data , 200) - with self._dvlock: - self._datavalid.clear() + if self.finishedSending(): + with self._dvlock: + self._datavalid.clear() + + def finishedSending(self): + if (len(self._alarms) + len(self._data) + len(self._commands)) > 0: + return False + else: + return True def receiver(self): while self._receiving: if self._serial is not None: if self._serial.in_waiting > 0: - with self._lock: + with self._lockSerial: logging.debug("Receiving data...") data = self._serial.read(self._serial.in_waiting) self.processPacket(data) @@ -91,7 +96,7 @@ class commsControl(): logging.debug(f'Queue length: {len(queue)}') currentTime = int(round(time.time() * 1000)) if currentTime > (self._timeLastTransmission + timeout): - with self._lock: + with self._lockSerial: self._timeLastTransmission = currentTime queue[0].setSequenceSend(self._sequenceSend) self.sendPacket(queue[0]) @@ -154,8 +159,6 @@ class commsControl(): else: sequenceReceive = ((control >> 1) & 0x7F) + 1 address = tmpComms.getData()[tmpComms.getAddress():tmpComms.getControl()] - - #payload = tmpComms.getData()[tmpComms.getInformation() : tmpComms.getFcs()] if self.receivePacket(payloadType, tmpComms): logging.debug("Preparing ACK") @@ -169,7 +172,7 @@ class commsControl(): self._received.clear() self._foundStart = False - self._receivedStart = -1 + self._receivedStart = -1 def writePayload(self, payload): payloadType = payload.getType()