diff --git a/DeviceAdapters/Arduino/AOTFcontroller/AOTFcontroller.ino b/DeviceAdapters/Arduino/AOTFcontroller/AOTFcontroller.ino index 013ae9749..a85418b4c 100644 --- a/DeviceAdapters/Arduino/AOTFcontroller/AOTFcontroller.ino +++ b/DeviceAdapters/Arduino/AOTFcontroller/AOTFcontroller.ino @@ -26,7 +26,7 @@ * * * Set digital patten for triggered mode: 5xd - * Where x is the number of the pattern (currently, 12 patterns can be stored). + * Where x is the number of the pattern (Quesry the max number of patterns with 32, default is 12, but number can be changed in the firmware). * and d is the digital pattern to be stored at that position. Note that x should * be the real number (i.e., not ASCI encoded) * Controller will return 5xd @@ -90,6 +90,11 @@ * Get Version: 31 * Returns: version number (as ASCI string) \r\n * + * Get Max number of patterns that can be uploaded: 32 + * Returns: Max number of patterns as an unsigned int, 2 bytes, highbyte first + * Available as of version 3 + * + * * Read digital state of analogue input pins 0-5: 40 * Returns raw value of PINC (two high bits are not used) * @@ -104,7 +109,7 @@ * Get Number of digital patterns */ - unsigned int version_ = 2; + unsigned int version_ = 3; // pin on which to receive the trigger (2 and 3 can be used with interrupts, although this code does not use interrupts) int inPin_ = 2; @@ -118,9 +123,9 @@ // pin connected to CS of TLV5618 int latchPin = 5; - const int SEQUENCELENGTH = 12; // this should be good enough for everybody;) - byte triggerPattern_[SEQUENCELENGTH] = {0,0,0,0,0,0,0,0,0,0,0,0}; - unsigned int triggerDelay_[SEQUENCELENGTH] = {0,0,0,0,0,0,0,0,0,0,0,0}; + const uint16_t SEQUENCELENGTH = 256; // Can be increased, but pay attention that there is significant memory left for local variables + byte triggerPattern_[SEQUENCELENGTH]; + unsigned int triggerDelay_[SEQUENCELENGTH]; int patternLength_ = 0; byte repeatPattern_ = 0; volatile long triggerNr_; // total # of triggers in this run (0-based) @@ -154,6 +159,11 @@ PORTC = PORTC | B00111111; digitalWrite(latchPin, HIGH); + + for (unsigned int i = 0; i < SEQUENCELENGTH; i++) { + triggerPattern_[i] = 0; + triggerDelay_[i] = 0; + } } void loop() { @@ -337,6 +347,13 @@ Serial.println(version_); break; + // returns Maximum number of patterns for sequencing + case 32: + Serial.write( byte(32)); + Serial.write(highByte(SEQUENCELENGTH)); + Serial.write(lowByte(SEQUENCELENGTH)); + break; + case 40: Serial.write( byte(40)); Serial.write( PINC); diff --git a/DeviceAdapters/Arduino/Arduino.cpp b/DeviceAdapters/Arduino/Arduino.cpp index 185421c94..05f9aa582 100644 --- a/DeviceAdapters/Arduino/Arduino.cpp +++ b/DeviceAdapters/Arduino/Arduino.cpp @@ -33,7 +33,7 @@ const char* g_DeviceNameArduinoMagnifier = "Arduino-Magnifier"; // Global info about the state of the Arduino. This should be folded into a class const int g_Min_MMVersion = 1; -const int g_Max_MMVersion = 2; +const int g_Max_MMVersion = 3; const char* g_versionProp = "Version"; const char* g_normalLogicString = "Normal"; const char* g_invertedLogicString = "Inverted"; @@ -104,6 +104,7 @@ MODULE_API void DeleteDevice(MM::Device* pDevice) // CArduinoHub::CArduinoHub() : initialized_ (false), + maxNumPatterns_(12), version_(0), magnifier_(0), switchState_ (0), @@ -288,6 +289,36 @@ int CArduinoHub::Initialize() sversion << version_; CreateProperty(g_versionProp, sversion.str().c_str(), MM::Integer, true, pAct); + if (version_ >= 3) + { + unsigned char command[1]; + command[0] = 32; + + ret = WriteToComPortH((const unsigned char*) command, 1); + if (ret != DEVICE_OK) + return ret; + + MM::MMTime startTime = GetCurrentMMTime(); + const unsigned int nrBytes = 3; + unsigned long bytesRead = 0; + unsigned char answer[nrBytes] = { 0, 0, 0}; + while ((bytesRead < nrBytes) && ( (GetCurrentMMTime() - startTime).getMsec() < 250)) { + unsigned long br; + ret = ReadFromComPortH(answer + bytesRead, nrBytes - bytesRead, br); + if (ret != DEVICE_OK) + return ret; + bytesRead += br; + } + + if (answer[0] != 32) + return ERR_COMMUNICATION; + + unsigned int tmp = answer[1]; + tmp = tmp << 8; + tmp = tmp | answer[2]; + maxNumPatterns_ = tmp; + } + ret = UpdateStatus(); if (ret != DEVICE_OK) return ret; @@ -401,6 +432,7 @@ int CArduinoHub::RegisterMagnifier(CArduinoMagnifier* magnifier) // ~~~~~~~~~~~~~~~~~~~~~~~~~~ CArduinoSwitch::CArduinoSwitch() : + numPatterns_(12), hub_(0), nrPatternsUsed_(0), currentDelay_(0), @@ -420,8 +452,6 @@ CArduinoSwitch::CArduinoSwitch() : SetErrorText(ERR_COMMUNICATION, "Error in communication with Arduino board"); SetErrorText(ERR_NO_PORT_SET, "Hub Device not found. The Arduino Hub device is needed to create this device"); - for (unsigned int i=0; i < NUMPATTERNS; i++) - pattern_[i] = 0; // Description int ret = CreateProperty(MM::g_Keyword_Description, "Arduino digital output driver", MM::String, true); @@ -537,6 +567,9 @@ int CArduinoSwitch::Initialize() SetPropertyLimits("Repeat Timed Pattern", 0, 255); */ + // ask the hub for numPatterns_ + numPatterns_ = hub_->GetMaxNumPatterns(); + nRet = UpdateStatus(); if (nRet != DEVICE_OK) return nRet; @@ -671,14 +704,14 @@ int CArduinoSwitch::OnState(MM::PropertyBase* pProp, MM::ActionType eAct) else if (eAct == MM::IsSequenceable) { if (sequenceOn_) - pProp->SetSequenceable(NUMPATTERNS); + pProp->SetSequenceable(numPatterns_); else pProp->SetSequenceable(0); } else if (eAct == MM::AfterLoadSequence) { std::vector sequence = pProp->GetSequence(); - if (sequence.size() > NUMPATTERNS) + if (sequence.size() > numPatterns_) return DEVICE_SEQUENCE_TOO_LARGE; unsigned char* seq = new unsigned char[sequence.size()]; for (unsigned int i=0; i < sequence.size(); i++) @@ -1548,6 +1581,7 @@ bool CArduinoInput::Busy() return false; } + int CArduinoInput::GetDigitalInput(long* state) { const std::lock_guard lock(hub_->GetLock()); @@ -1615,9 +1649,7 @@ int CArduinoInput::OnAnalogInput(MM::PropertyBase* pProp, MM::ActionType eAct, l { const std::lock_guard lock(hub_->GetLock()); - unsigned char command[2]; - command[0] = 41; - command[1] = (unsigned char) channel; + unsigned char command[2] = { 41, (unsigned char) channel }; int ret = hub_->WriteToComPortH((const unsigned char*) command, 2); if (ret != DEVICE_OK) @@ -1656,7 +1688,7 @@ int CArduinoInput::SetPullUp(int pin, int state) if (ret != DEVICE_OK) return ret; - unsigned char answer[3]; + unsigned char answer[3] = { 0, 0, 0 }; ret = ReadNBytes(hub_, 3, answer); if (ret != DEVICE_OK) return ret; diff --git a/DeviceAdapters/Arduino/Arduino.h b/DeviceAdapters/Arduino/Arduino.h index 4f7a3e7dc..690808851 100644 --- a/DeviceAdapters/Arduino/Arduino.h +++ b/DeviceAdapters/Arduino/Arduino.h @@ -57,6 +57,9 @@ class CArduinoHub : public HubBase int OnPort(MM::PropertyBase* pPropt, MM::ActionType eAct); int OnLogic(MM::PropertyBase* pPropt, MM::ActionType eAct); int OnVersion(MM::PropertyBase* pPropt, MM::ActionType eAct); + unsigned int GetMaxNumPatterns() { + return maxNumPatterns_; + }; // custom interface for child devices bool IsPortAvailable() {return portAvailable_;} @@ -86,6 +89,7 @@ class CArduinoHub : public HubBase bool invertedLogic_; bool timedOutputActive_; int version_; + unsigned int maxNumPatterns_; CArduinoMagnifier* magnifier_; std::mutex mutex_; unsigned switchState_; @@ -158,7 +162,7 @@ class CArduinoSwitch : public CStateDeviceBase int OnSequence(MM::PropertyBase* pProp, MM::ActionType eAct); private: - static const unsigned int NUMPATTERNS = 12; + unsigned int numPatterns_; CArduinoHub* hub_; //int OpenPort(const char* pszName, long lnValue); @@ -166,8 +170,6 @@ class CArduinoSwitch : public CStateDeviceBase //int ClosePort(); int LoadSequence(unsigned size, unsigned char* seq); - unsigned pattern_[NUMPATTERNS]; - unsigned delay_[NUMPATTERNS]; int nrPatternsUsed_; unsigned currentDelay_; bool sequenceOn_;