diff --git a/Source/Processors/Serial/PulsePal.cpp b/Source/Processors/Serial/PulsePal.cpp index b939e395bad8d1f2dc295d543927ecde5ed60b3c..a4ef5c8412f48f959b83e858c3ba0260ebe19530 100644 --- a/Source/Processors/Serial/PulsePal.cpp +++ b/Source/Processors/Serial/PulsePal.cpp @@ -20,12 +20,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +// Modified by JS 1/30/2014: Updated op codes for firmware 0_4, added new functions (indicated in comments below) #include <vector> #include <stdio.h> #include <stdint.h> - - #include "PulsePal.h" #define ZERO_uS (uint32_t) 0 @@ -33,6 +32,7 @@ #define MAX_uS (uint32_t) 3600000000 #define NEWLINE 0xA #define RETURN 0xD +#define makeLong(msb, byte2, byte3, lsb) ((msb << 24) | (byte2 << 16) | (byte3 << 8) | (lsb)) //JS 2/1/2014 PulsePal::PulsePal() { @@ -41,7 +41,7 @@ PulsePal::PulsePal() PulsePal::~PulsePal() { - + disconnectClient(); serial.close(); } @@ -64,108 +64,153 @@ void PulsePal::initialize() // bool foundDevice = false; - int id = devices[0].getDeviceID(); + int id = devices[0].getDeviceID(); string path = devices[0].getDevicePath(); string name = devices[0].getDeviceName(); - serial.setup(id, 115200); //115200); - + serial.setup(id, 115200); + std::cout << "Found!" << std::endl; +} + +uint32_t PulsePal::getFirmwareVersion() // JS 1/30/2014 +{ + uint32_t firmwareVersion = 0; + uint8_t handshakeByte = 72; + uint8_t responseBytes[5] = { 0 }; + serial.writeByte(handshakeByte); + Sleep(100); + serial.readBytes(responseBytes,5); + firmwareVersion = makeLong(responseBytes[4], responseBytes[3], responseBytes[2], responseBytes[1]); + return firmwareVersion; +} + +void PulsePal::setBiphasic(uint8_t channel, bool isBiphasic) +{ + uint8_t command = 0; + + if (isBiphasic) + { + command = 1; + } + program(channel, 1, command); + PulsePal::currentOutputParams[channel].isBiphasic = command; //JS 2/1/2014 (Added this for all single-item programming functions) } +void PulsePal::setPhase1Voltage(uint8_t channel, float voltage) +{ + program(channel, 2, voltageToByte(voltage)); + PulsePal::currentOutputParams[channel].phase1Voltage = voltage; +} +void PulsePal::setPhase2Voltage(uint8_t channel, float voltage) +{ + program(channel, 3, voltageToByte(voltage)); + PulsePal::currentOutputParams[channel].phase2Voltage = voltage; +} -void PulsePal::setPhase1Duration(uint8_t channel, uint32_t timeInMicroseconds) +void PulsePal::setPhase1Duration(uint8_t channel, float timeInSeconds) { + uint32_t timeInMicroseconds = (uint32_t)(timeInSeconds * 1000000); //JS 2/1/2014 constrain(&timeInMicroseconds, FIFTY_uS, MAX_uS); - program(channel, 0, timeInMicroseconds); + program(channel, 4, timeInMicroseconds); + PulsePal::currentOutputParams[channel].phase1Duration = timeInSeconds; } -void PulsePal::setInterPhaseInterval(uint8_t channel, uint32_t timeInMicroseconds) +void PulsePal::setInterPhaseInterval(uint8_t channel, float timeInSeconds) { + uint32_t timeInMicroseconds = (uint32_t)(timeInSeconds * 1000000); constrain(&timeInMicroseconds, FIFTY_uS, MAX_uS); - program(channel, 1, timeInMicroseconds); + program(channel, 5, timeInMicroseconds); + PulsePal::currentOutputParams[channel].interPhaseInterval = timeInSeconds; } -void PulsePal::setPhase2Duration(uint8_t channel, uint32_t timeInMicroseconds) +void PulsePal::setPhase2Duration(uint8_t channel, float timeInSeconds) { + uint32_t timeInMicroseconds = (uint32_t)(timeInSeconds * 1000000); constrain(&timeInMicroseconds, FIFTY_uS, MAX_uS); - program(channel, 2, timeInMicroseconds); + program(channel, 6, timeInMicroseconds); + PulsePal::currentOutputParams[channel].phase2Duration = timeInSeconds; } -void PulsePal::setInterPulseInterval(uint8_t channel, uint32_t timeInMicroseconds) +void PulsePal::setInterPulseInterval(uint8_t channel, float timeInSeconds) { + uint32_t timeInMicroseconds = (uint32_t)(timeInSeconds * 1000000); constrain(&timeInMicroseconds, FIFTY_uS, MAX_uS); - program(channel, 3, timeInMicroseconds); + program(channel, 7, timeInMicroseconds); + PulsePal::currentOutputParams[channel].interPhaseInterval = timeInSeconds; } -void PulsePal::setBurstDuration(uint8_t channel, uint32_t timeInMicroseconds) +void PulsePal::setBurstDuration(uint8_t channel, float timeInSeconds) { + uint32_t timeInMicroseconds = (uint32_t)(timeInSeconds * 1000000); constrain(&timeInMicroseconds, ZERO_uS, MAX_uS); - program(channel, 4, timeInMicroseconds); + program(channel, 8, timeInMicroseconds); + PulsePal::currentOutputParams[channel].burstDuration = timeInSeconds; } -void PulsePal::setBurstInterval(uint8_t channel, uint32_t timeInMicroseconds) +void PulsePal::setBurstInterval(uint8_t channel, float timeInSeconds) { + uint32_t timeInMicroseconds = (uint32_t)(timeInSeconds * 1000000); constrain(&timeInMicroseconds, ZERO_uS, MAX_uS); - program(channel, 5, timeInMicroseconds); + program(channel, 9, timeInMicroseconds); + PulsePal::currentOutputParams[channel].interBurstInterval = timeInSeconds; } -void PulsePal::setStimulusTrainDuration(uint8_t channel, uint32_t timeInMicroseconds) +void PulsePal::setPulseTrainDuration(uint8_t channel, float timeInSeconds) { + uint32_t timeInMicroseconds = (uint32_t)(timeInSeconds * 1000000); constrain(&timeInMicroseconds, FIFTY_uS, MAX_uS); - program(channel, 6, timeInMicroseconds); + program(channel, 10, timeInMicroseconds); + PulsePal::currentOutputParams[channel].pulseTrainDuration = timeInSeconds; } -void PulsePal::setStimulusTrainDelay(uint8_t channel, uint32_t timeInMicroseconds) +void PulsePal::setPulseTrainDelay(uint8_t channel, float timeInSeconds) { + uint32_t timeInMicroseconds = (uint32_t)(timeInSeconds * 1000000); constrain(&timeInMicroseconds, FIFTY_uS, MAX_uS); - program(channel, 7, timeInMicroseconds); + program(channel, 11, timeInMicroseconds); + PulsePal::currentOutputParams[channel].pulseTrainDelay = timeInSeconds; } -void PulsePal::setBiphasic(uint8_t channel, bool isBiphasic) +void PulsePal::setTrigger1Link(uint8_t channel, uint8_t link_state) // JS 1/30/2014 { - uint8_t command = 0; - - if (isBiphasic) - { - command = 1; - } - - program(channel, 8, command); + program(channel, 12, link_state); + PulsePal::currentOutputParams[channel].linkTriggerChannel1 = link_state; } - -void PulsePal::setPhase1Voltage(uint8_t channel, float voltage) +void PulsePal::setTrigger2Link(uint8_t channel, uint8_t link_state) // JS 1/30/2014 { - program(channel, 9, voltageToByte(voltage)); + program(channel, 13, link_state); + PulsePal::currentOutputParams[channel].linkTriggerChannel2 = link_state; } - -void PulsePal::setPhase2Voltage(uint8_t channel, float voltage) +void PulsePal::setCustomTrainID(uint8_t channel, uint8_t ID) // JS 1/30/2014 { - program(channel, 10, voltageToByte(voltage)); + program(channel, 14, ID); + PulsePal::currentOutputParams[channel].customTrainID = ID; } - -void PulsePal::updateDisplay(string line1, string line2) +void PulsePal::setCustomTrainTarget(uint8_t channel, uint8_t target) // JS 1/30/2014 { - uint8_t message1 = 85; - - serial.writeByte(message1); - - serial.writeBytes((unsigned char*) line1.data(), line1.size()); - //serial.writeByte(0); - //serial.writeByte(RETURN); - serial.writeByte(254); - serial.writeBytes((unsigned char*) line2.data(), line2.size()); - //serial.writeByte(0); - //serial.writeByte(RETURN); + program(channel, 15, target); + PulsePal::currentOutputParams[channel].customTrainTarget = target; +} +void PulsePal::setCustomTrainLoop(uint8_t channel, uint8_t loop_state) // JS 1/30/2014 +{ + program(channel, 16, loop_state); + PulsePal::currentOutputParams[channel].customTrainLoop = loop_state; +} +void PulsePal::setTriggerMode(uint8_t channel, uint8_t mode) // JS 1/30/2014 +{ + program(channel, 128, mode); + PulsePal::currentInputParams[channel].triggerMode = mode; } + void PulsePal::program(uint8_t channel, uint8_t paramCode, uint32_t paramValue) { - std::cout << "sending 32-bit message" << std::endl; + //std::cout << "sending 32-bit message" << std::endl; - uint8_t message1[3] = {79, paramCode, channel}; + uint8_t message1[3] = {74, paramCode, channel}; uint8_t message2[4]; @@ -178,32 +223,96 @@ void PulsePal::program(uint8_t channel, uint8_t paramCode, uint32_t paramValue) serial.writeBytes(message1, 3); serial.writeBytes(message2, 4); - std::cout << "Message 1: " << (int) message1[0] << " " << (int) message1[1] << " " << (int) message1[2] << std::endl; - std::cout << "Message 2: " << (int) message2[0] << " " << (int) message2[1] << " " << (int) message2[2] << " " << (int) message2[3] << std::endl; + //std::cout << "Message 1: " << (int) message1[0] << " " << (int) message1[1] << " " << (int) message1[2] << std::endl; + //std::cout << "Message 2: " << (int) message2[0] << " " << (int) message2[1] << " " << (int) message2[2] << " " << (int) message2[3] << std::endl; } void PulsePal::program(uint8_t channel, uint8_t paramCode, uint8_t paramValue) { - std::cout << "sending 8-bit message" << std::endl; + //std::cout << "sending 8-bit message" << std::endl; - uint8_t message1[3] = {79, paramCode, channel}; + uint8_t message1[3] = {74, paramCode, channel}; serial.writeBytes(message1, 3); serial.writeBytes(¶mValue, 1); - std::cout << "Message 1: " << (int) message1[0] << " " << (int) message1[1] << " " << (int) message1[2] << std::endl; - std::cout << "Message 2: " << paramValue << std::endl; + //std::cout << "Message 1: " << (int) message1[0] << " " << (int) message1[1] << " " << (int) message1[2] << std::endl; + //std::cout << "Message 2: " << paramValue << std::endl; } + + +void PulsePal::triggerChannel(uint8_t chan) +{ + const uint8_t code = 1 << (chan - 1); + + uint8_t bytesToWrite[2] = {77, code}; + + serial.writeBytes(bytesToWrite, 2); +} + +void PulsePal::triggerChannels(uint8_t channel1, uint8_t channel2, uint8_t channel3, uint8_t channel4) // JS 1/30/2014 +{ + uint8_t code = 0; + code = code + 1 * channel1; + code = code + 2 * channel2; + code = code + 4 * channel3; + code = code + 8 * channel4; + + uint8_t bytesToWrite[2] = { 77, code }; + + serial.writeBytes(bytesToWrite, 2); +} + +void PulsePal::updateDisplay(string line1, string line2) +{ + string Prefix; + string Message; + Message.append(line1); + Message += 254; + Message.append(line2); + Prefix += 78; + Prefix += Message.size(); + Prefix.append(Message); + serial.writeBytes((unsigned char*)Prefix.data(), Prefix.size()); +} + +void PulsePal::setFixedVoltage(uint8_t channel, float voltage) // JS 1/30/2014 +{ + uint8_t voltageByte = 0; + voltageByte = voltageToByte(voltage); + uint8_t message1[3] = { 79, channel, voltageByte }; + serial.writeBytes(message1, 3); +} + +void PulsePal::abortPulseTrains() // JS 1/30/2014 +{ + uint8_t message1 = 80; + serial.writeByte(message1); +} + +void PulsePal::disconnectClient() // JS 1/30/2014 +{ + uint8_t message1 = 81; + serial.writeByte(message1); +} + +void PulsePal::setContinuousLoop(uint8_t channel, uint8_t state) // JS 1/30/2014 +{ + uint8_t message1[3] = {82, channel, state}; + serial.writeBytes(message1, 3); +} + + void PulsePal::constrain(uint32_t* value, uint32_t min, uint32_t max) { - // value must be a multiple of 50 - if (*value % 50 > 0) + // value must be a multiple of 100 + if (*value % 100 > 0) { - *value = *value - (*value % 50); + *value = *value - (*value % 100); } if (*value < min) @@ -223,20 +332,133 @@ uint8_t PulsePal::voltageToByte(float voltage) // input: -10 to 10 V // output: 0-255 - uint8_t output = (uint8_t)((voltage+10)/20)*255; + uint8_t output = uint8_t(((voltage+10)/20)*255); return output; } +void PulsePal::programCustomTrain(uint8_t ID, uint8_t nPulses, float customPulseTimes[], float customVoltages[]){ + int nMessageBytes = (nPulses * 5) + 6; + // Convert voltages to bytes + uint8_t voltageBytes[1000] = { 0 }; + float thisVoltage = 0; + for (int i = 0; i < nPulses; i++) { + thisVoltage = customVoltages[i]; + voltageBytes[i] = voltageToByte(thisVoltage); + } + // Convert times to bytes + uint8_t pulseTimeBytes[4000] = { 0 }; + int pos = 0; + unsigned long pulseTimeMicroseconds; + for (int i = 0; i < nPulses; i++){ + pulseTimeMicroseconds = (unsigned long)(customPulseTimes[i] * 1000000); + pulseTimeBytes[pos] = (uint8_t)(pulseTimeMicroseconds); pos++; + pulseTimeBytes[pos] = (uint8_t)(pulseTimeMicroseconds >> 8); pos++; + pulseTimeBytes[pos] = (uint8_t)(pulseTimeMicroseconds >> 16); pos++; + pulseTimeBytes[pos] = (uint8_t)(pulseTimeMicroseconds >> 24); pos++; + } + uint8_t *messageBytes = new uint8_t[nMessageBytes]; + if (ID == 2) { + messageBytes[0] = 76; // Op code to program custom train 2 + } + else { + messageBytes[0] = 75; // Op code to program custom train 1 + } + messageBytes[1] = 0; // USB packet correction byte + messageBytes[2] = (uint8_t)(nPulses); + messageBytes[3] = (uint8_t)(nPulses >> 8); + messageBytes[4] = (uint8_t)(nPulses >> 16); + messageBytes[5] = (uint8_t)(nPulses >> 24); + int timeDataEnd = 6 + (nPulses * 4); + for (int i = 6; i < timeDataEnd; i++){ + messageBytes[i] = pulseTimeBytes[i - 6]; + } + for (int i = timeDataEnd; i < nMessageBytes; i++){ + messageBytes[i] = voltageBytes[i - timeDataEnd]; + } + serial.writeBytes(messageBytes, nMessageBytes); +} + +void PulsePal::programAllParams() { + uint8_t messageBytes[163] = { 0 }; + messageBytes[0] = 73; + int pos = 1; + uint32_t thisTime = 0; + float thisVoltage = 0; + uint8_t thisVoltageByte = 0; + + // add time params + for (int i = 1; i < 5; i++){ + thisTime = (uint32_t)(currentOutputParams[i].phase1Duration * 1000000); + messageBytes[pos] = (uint8_t)(thisTime); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 8); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 16); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 24); pos++; + thisTime = (uint32_t)(currentOutputParams[i].interPhaseInterval * 1000000); + messageBytes[pos] = (uint8_t)(thisTime); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 8); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 16); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 24); pos++; + thisTime = (uint32_t)(currentOutputParams[i].phase2Duration * 1000000); + messageBytes[pos] = (uint8_t)(thisTime); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 8); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 16); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 24); pos++; + thisTime = (uint32_t)(currentOutputParams[i].interPulseInterval * 1000000); + messageBytes[pos] = (uint8_t)(thisTime); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 8); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 16); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 24); pos++; + thisTime = (uint32_t)(currentOutputParams[i].burstDuration * 1000000); + messageBytes[pos] = (uint8_t)(thisTime); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 8); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 16); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 24); pos++; + thisTime = (uint32_t)(currentOutputParams[i].interBurstInterval * 1000000); + messageBytes[pos] = (uint8_t)(thisTime); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 8); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 16); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 24); pos++; + thisTime = (uint32_t)(currentOutputParams[i].pulseTrainDuration * 1000000); + messageBytes[pos] = (uint8_t)(thisTime); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 8); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 16); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 24); pos++; + thisTime = (uint32_t)(currentOutputParams[i].pulseTrainDelay * 1000000); + messageBytes[pos] = (uint8_t)(thisTime); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 8); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 16); pos++; + messageBytes[pos] = (uint8_t)(thisTime >> 24); pos++; + } -void PulsePal::triggerChannel(uint8_t chan) -{ - const uint8_t code = 1 << (chan-1); + // add single-byte params + for (int i = 1; i < 5; i++){ + messageBytes[pos] = (uint8_t)currentOutputParams[i].isBiphasic; pos++; + thisVoltage = PulsePal::currentOutputParams[i].phase1Voltage; + thisVoltageByte = voltageToByte(thisVoltage); + messageBytes[pos] = thisVoltageByte; pos++; + thisVoltage = PulsePal::currentOutputParams[i].phase2Voltage; + thisVoltageByte = voltageToByte(thisVoltage); + messageBytes[pos] = thisVoltageByte; pos++; + messageBytes[pos] = (uint8_t)currentOutputParams[i].customTrainID; pos++; + messageBytes[pos] = (uint8_t)currentOutputParams[i].customTrainTarget; pos++; + messageBytes[pos] = (uint8_t)currentOutputParams[i].customTrainLoop; pos++; + } - uint8_t bytesToWrite[2] = {84, code}; + // add trigger channel 1 links + for (int i = 1; i < 5; i++){ + messageBytes[pos] = (uint8_t)currentOutputParams[i].linkTriggerChannel1; pos++; + } + // add trigger channel 2 links + for (int i = 1; i < 5; i++){ + messageBytes[pos] = (uint8_t)currentOutputParams[i].linkTriggerChannel2; pos++; + } - serial.writeBytes(bytesToWrite, 2); -} + // add trigger channel modes + messageBytes[pos] = (uint8_t)currentInputParams[1].triggerMode; pos++; + messageBytes[pos] = (uint8_t)currentInputParams[2].triggerMode; pos++; + serial.writeBytes(messageBytes, 163); +} \ No newline at end of file diff --git a/Source/Processors/Serial/PulsePal.h b/Source/Processors/Serial/PulsePal.h index 9b8bb2ad0a3fbdaaec11dda7ca97dc3b88423cc9..3e9167a93c4355731c05b6466822f950b14ab682 100644 --- a/Source/Processors/Serial/PulsePal.h +++ b/Source/Processors/Serial/PulsePal.h @@ -21,6 +21,8 @@ */ +// Modified by JS 1/30/2014: Updated op codes for firmware 0_4, added new functions (indicated in comments below) + #ifndef __PULSEPAL_H_F2B7B63E__ #define __PULSEPAL_H_F2B7B63E__ @@ -29,11 +31,7 @@ #include "ofSerial.h" /** - - Interfaces with the PulsePal from Lucid Biosystems - - (www.lucidbiosystems.com) - + Interface to PulsePal @see PulsePalOutput */ @@ -41,40 +39,77 @@ class PulsePal { public: + + // Initialization and termination PulsePal(); ~PulsePal(); - void initialize(); + uint32_t PulsePal::getFirmwareVersion(); + void disconnectClient(); - void setPhase1Duration(uint8_t channel, uint32_t timeInMicroseconds); - void setInterPhaseInterval(uint8_t channel, uint32_t timeInMicroseconds); - void setPhase2Duration(uint8_t channel, uint32_t timeInMicroseconds); - void setInterPulseInterval(uint8_t channel, uint32_t timeInMicroseconds); - void setBurstDuration(uint8_t channel, uint32_t timeInMicroseconds); - void setBurstInterval(uint8_t channel, uint32_t timeInMicroseconds); - void setStimulusTrainDuration(uint8_t channel, uint32_t timeInMicroseconds); - void setStimulusTrainDelay(uint8_t channel, uint32_t timeInMicroseconds); + // Program single parameter void setBiphasic(uint8_t channel, bool isBiphasic); void setPhase1Voltage(uint8_t channel, float voltage); void setPhase2Voltage(uint8_t channel, float voltage); - + void setPhase1Duration(uint8_t channel, float timeInSeconds); + void setInterPhaseInterval(uint8_t channel, float timeInSeconds); + void setPhase2Duration(uint8_t channel, float timeInSeconds); + void setInterPulseInterval(uint8_t channel, float timeInSeconds); + void setBurstDuration(uint8_t channel, float timeInSeconds); + void setBurstInterval(uint8_t channel, float timeInSeconds); + void setPulseTrainDuration(uint8_t channel, float timeInSeconds); + void setPulseTrainDelay(uint8_t channel, float timeInSeconds); + void setTrigger1Link(uint8_t channel, uint8_t link_state); + void setTrigger2Link(uint8_t channel, uint8_t link_state); + void setCustomTrainID(uint8_t channel, uint8_t ID); // ID = 0: no custom train. ID = 1-2: custom trains 1 or 2 + void setCustomTrainTarget(uint8_t channel, uint8_t target); // target = 0: Custom times define pulses Target = 1: They define bursts + void setCustomTrainLoop(uint8_t channel, uint8_t loop_state); // loop_state = 0: No loop 1: loop + + // Program all parameters + void programAllParams(); + + // Program custom pulse train + void programCustomTrain(uint8_t ID, uint8_t nPulses, float customPulseTimes[], float customVoltages[]); + + // Operations and settings void triggerChannel(uint8_t channel); - + void triggerChannels(uint8_t channel1, uint8_t channel2, uint8_t channel3, uint8_t channel4); void updateDisplay(string line1, string line2); + void setFixedVoltage(uint8_t channel, float voltage); + void abortPulseTrains(); + void setContinuousLoop(uint8_t channel, uint8_t state); + void setTriggerMode(uint8_t channel, uint8_t mode); + + // Fields + struct OutputParams { + int isBiphasic = 0; + float phase1Voltage = 5; + float phase2Voltage = -5; + float phase1Duration = 0.001; + float interPhaseInterval = 0.001; + float phase2Duration = 0.001; + float interPulseInterval = 0.01; + float burstDuration = 0; + float interBurstInterval = 0; + float pulseTrainDuration = 1; + float pulseTrainDelay = 0; + int linkTriggerChannel1 = 1; + int linkTriggerChannel2 = 0; + int customTrainID = 0; + int customTrainTarget = 0; + int customTrainLoop = 0; + } currentOutputParams[5]; // Use 1-indexing for the channels (output channels 1-4 = currentOutputParams[1]-currentOutputParams[4]) + struct InputParams { + int triggerMode; + } currentInputParams[3]; // Use 1-indexing for the trigger channels private: - void constrain(uint32_t* value, uint32_t min, uint32_t max); - void program(uint8_t channel, uint8_t paramCode, uint32_t paramValue); void program(uint8_t channel, uint8_t paramCode, uint8_t paramValue); - uint8_t voltageToByte(float voltage); - ofSerial serial; }; - - -#endif // __PULSEPAL_H_F2B7B63E__ +#endif // __PULSEPAL_H_F2B7B63E__ \ No newline at end of file