Serial Wombat Arduino Library
Loading...
Searching...
No Matches
SerialWombatAbstractScaledOutput.h
Go to the documentation of this file.
1#pragma once
2/*
3Copyright 2021-2025 Broadwell Consulting Inc.
4
5"Serial Wombat" is a registered trademark of Broadwell Consulting Inc. in
6the United States. See SerialWombat.com for usage guidance.
7
8Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14
15The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
25*/
26
27#include "SerialWombat.h"
28#include "limits.h"
29
32
33
64{
65public:
72
86
92
93
109 int16_t writeTimeout(uint16_t timeout_mS, uint16_t timeoutOutputValue)
110 {
111
112 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
113 pin(),
115 1,
116 SW_LE16(timeout_mS),
117 SW_LE16(timeoutOutputValue),
118 };
119
120 int16_t result = _asosw.sendPacket(tx);
121
122 return(result);
123
124 }
125
153 uint8_t endstop0Pin = 0xFF,
154 uint16_t endstop0TriggerValue = 0x0000,
155 uint16_t endstop0OutputValue = 0x0000,
156 bool endstop0GreaterThanOrEqual = false,
157 uint8_t endstop1Pin = 0xFF,
158 uint16_t endstop1TriggerValue = 0x0000,
159 uint16_t endstop1OutputValue = 0x0000,
160 bool endstop1GreaterThanOrEqual = false)
161 {
162
163 {
164 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
165 pin(),
167 0x0C, // Set endstop 0 trigger and output values
168 SW_LE16(endstop0TriggerValue),
169 SW_LE16(endstop0OutputValue)
170 };
171 int16_t result = _asosw.sendPacket(tx);
172 if (result < 0)
173 {
174 return(result);
175 }
176 }
177
178 {
179 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
180 pin(),
182 0x0D, // Set endstop 1 trigger and output values
183 SW_LE16(endstop1TriggerValue),
184 SW_LE16(endstop1OutputValue)
185 };
186 int16_t result = _asosw.sendPacket(tx);
187 if (result < 0)
188 {
189 return(result);
190 }
191 }
192 {
193 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
194 pin(),
196 0x0B, // Set endstop pins and comparison modes
197 endstop0Pin,
198 (uint8_t)(endstop0GreaterThanOrEqual ? 1 : 0),
199 endstop1Pin,
200 (uint8_t)(endstop1GreaterThanOrEqual ? 1 : 0)
201 };
202 return(_asosw.sendPacket(tx));
203
204 }
205
206 }
207
216 int16_t writeScalingEnabled(bool enabled, uint8_t sourcePin)
217 {
218 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
219 pin(), swPinModeNumber(),
220 0, //Enable/disable scaling, set source pin
221 enabled,
222 sourcePin,
223 0x55, 0x55};
224
225 int16_t result = _asosw.sendPacket(tx);
226 return(result);
227 }
228
242 int16_t writeInputScaling(uint16_t inputMin, uint16_t inputMax)
243 {
244 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
245 pin(),
247 2, // Set input scaling
248 SW_LE16(inputMin),
249 SW_LE16(inputMax),
250 };
251 return(_asosw.sendPacket(tx));
252 }
253
269 int16_t writeOutputScaling(uint16_t outputMin, uint16_t outputMax)
270 {
271 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
272 pin(),
274 5, //Set output scaling
275 SW_LE16(outputMin),
276 SW_LE16(outputMax),
277 };
278 return(_asosw.sendPacket(tx));
279 }
280
288 int16_t writeScalingInvertedInput(bool inverted)
289 {
290 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
291 pin(),
293 3, // Set inverted/not inverted
294 inverted,
295 0x55,0x55,0x55,
296 };
297 return(_asosw.sendPacket(tx));
298 }
299
312 int16_t writeScalingTargetValue(uint16_t target)
313 {
314 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
315 pin(),
317 6, // Set target value for PID controller
318 SW_LE16(target),0x55,0x55,
319 };
320 return(_asosw.sendPacket(tx));
321 }
322
337 int16_t writeRateControl(Period samplePeriod, uint16_t maximumChangecounts, uint16_t maximumDecrementCounts = 0)
338 {
339 {
340 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
341 pin(),
343 4, // Set filter mode
344 1, // Filter mode rate control
345 SW_LE16(maximumChangecounts),0x55,
346 };
347 int16_t result = _asosw.sendPacket(tx);
348 if (result < 0)
349 {
350 return(result);
351 }
352 }
353 if (maximumDecrementCounts > 0)
354 {
355 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
356 pin(),
358 8, // Set filter mode
359 SW_LE16(maximumDecrementCounts),0x55,0x55
360 };
361 int16_t result = _asosw.sendPacket(tx);
362 if (result < 0)
363 {
364 return(result);
365 }
366 }
367 {
368 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
369 pin(),
371 7, // Set Sample Rate
372 (uint8_t)samplePeriod,
373 0x55,0x55,0x55,
374 };
375 return(_asosw.sendPacket(tx));
376 }
377 }
378
392 int16_t write1stOrderFiltering(Period samplePeriod, uint16_t filterConstant)
393 {
394 {
395 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
396 pin(),
398 4, // Set filter mode
399 2, // Filter mode 1st Order
400 SW_LE16(filterConstant),0x55,
401 };
402 int16_t result = _asosw.sendPacket(tx);
403 if (result < 0)
404 {
405 return(result);
406 }
407 }
408 {
409 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
410 pin(),
412 7, // Set Sample Rate
413 (uint8_t)samplePeriod,
414 0x55,0x55,0x55,
415 };
416 return(_asosw.sendPacket(tx));
417 }
418 }
419
434 int16_t writeHysteresis(uint16_t lowLimit, uint16_t lowOutputValue, uint16_t highLimit, uint16_t highOutputValue, uint16_t initialOutputValue)
435 {
436 {
437 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
438 pin(),
440 50, // Set hysteresis high limit/output
441 SW_LE16(highLimit),
442 SW_LE16(highOutputValue)
443 };
444 int16_t result = _asosw.sendPacket(tx); if (result < 0) { return(result); }
445 }
446
447 {
448 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
449 pin(),
451 51, // Set hysteresis low limit/output
452 SW_LE16(lowLimit),
453 SW_LE16(lowOutputValue)
454 };
455 int16_t result = _asosw.sendPacket(tx); if (result < 0) { return(result); }
456 }
457 {
458 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
459 pin(),
461 52, // Set hysteresis low limit/output
462 SW_LE16(initialOutputValue),
463 0x55,0x55
464 };
465 int16_t result = _asosw.sendPacket(tx); if (result < 0) { return(result); }
466 }
467 return(0);
468 }
469
490 int16_t writeRamp(uint16_t slowIncrement, uint16_t incrementThreshold, uint16_t fastIncrement,Period samplePeriod, RampMode rampMode)
491 {
492 {
493 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
494 pin(),
496 7, // Set Sample Rate
497 (uint8_t) samplePeriod,
498 0x55,0x55,0x55
499 };
500 int16_t result = _asosw.sendPacket(tx); if (result < 0) { return(result); }
501 }
502 {
503 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
504 pin(),
506 60, // Set ramp slow increment, threshold
507 SW_LE16(slowIncrement),
508 SW_LE16(incrementThreshold)
509
510 };
511 int16_t result = _asosw.sendPacket(tx); if (result < 0) { return(result); }
512 }
513 {
514 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
515 pin(),
517 61, // Set ramp fast increment, mode
518 SW_LE16(fastIncrement),
519 (uint8_t) rampMode, 0x55
520 };
521 int16_t result = _asosw.sendPacket(tx); if (result < 0) { return(result); }
522 }
523 return 0;
524
525 }
526
562 int16_t writePID(uint16_t kp, uint16_t ki, uint16_t kd,uint16_t target,Period samplePeriod, uint8_t targetPin = 255, bool biDirectional = false)
563 {
564 {
565 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
566 pin(),
568 100, // Set kp and ki
569 SW_LE16(kp),
570 SW_LE16(ki)
571 };
572 int16_t result = _asosw.sendPacket(tx); if (result < 0) { return(result); }
573 }
574 {
575 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
576 pin(),
578 101, // Set kd
579 SW_LE16(kd),
580 0x55,0x55
581 };
582 int16_t result = _asosw.sendPacket(tx); if (result < 0) { return(result); }
583 }
585 {
586 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
587 pin(),
589 7, // Set Sample Rate
590 (uint8_t)samplePeriod,
591 0x55,0x55,0x55,
592 };
593 int16_t result = _asosw.sendPacket(tx); if (result < 0) { return(result); }
594 }
595 {
596 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
597 pin(),
599 102, // Reset Integrator
600 0x55,0x55,0x55,0x55
601 };
602 int16_t result = _asosw.sendPacket(tx); if (result < 0) { return(result); }
603 }
604 {
605 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
606 pin(),
608 109, // Configure target and bidirectional
609 targetPin,
610 biDirectional,
611 0x55,0x55
612 };
613 int16_t result = _asosw.sendPacket(tx); if (result < 0) { return(result); }
614 }
615 return 0;
616
617 }
618
619
628 {
629 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
630 pin(),
632 9, // Read Last Value
633 0x55, 0x55,0x55,0x55,
634 };
635 uint8_t rx[8];
636 if (_asosw.sendPacket(tx, rx) >= 0)
637 {
638 return(rx[4] + (uint16_t)rx[5] * 256);
639 }
640 else
641 {
642 return (0);
643 }
644
645 }
646
648 {
649 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
650 pin(),
652 110, // Write target Value and Reset Integrator
653 (byte)(target & 0xFF),(byte)(target >> 8),0x55,0x55
654 };
655 return _asosw.sendPacket(tx);
656 }
658 {
659 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
660 pin(),
662 103, // Get Last Error
663 0x55,0x55,0x55,0x55
664 };
665 uint8_t rx[8];
666
667 _asosw.sendPacket(tx, rx);
668 int32_t returnVal;
669 memcpy(&returnVal,&rx[4],4);
670 return returnVal;
671
672 }
673
674
676 {
677 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
678 pin(),
680 104, // Get Last Integrator
681 0x55,0x55,0x55,0x55
682 };
683 uint8_t rx[8];
684
685 _asosw.sendPacket(tx, rx);
686
687 int32_t returnVal;
688 memcpy(&returnVal,&rx[4],4);
689 return returnVal;
690 }
691
693 {
694 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
695 pin(),
697 105, // Get Last Integrator Effort
698 0x55,0x55,0x55,0x55
699 };
700 uint8_t rx[8];
701
702 _asosw.sendPacket(tx, rx);
703
704 int32_t returnVal;
705 memcpy(&returnVal,&rx[4],4);
706 return returnVal;
707 }
708
710 {
711 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
712 pin(),
714 106, // Get Last Proportional Effort
715 0x55,0x55,0x55,0x55
716 };
717 uint8_t rx[8];
718
719 _asosw.sendPacket(tx, rx);
720
721 int32_t returnVal;
722 memcpy(&returnVal,&rx[4],4);
723 return returnVal;
724 }
725
727 {
728 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
729 pin(),
731 107, // Get Last Derivative Effort
732 0x55,0x55,0x55,0x55
733 };
734 uint8_t rx[8];
735
736 _asosw.sendPacket(tx, rx);
737
738 int32_t returnVal;
739 memcpy(&returnVal,&rx[4],4);
740 return returnVal;
741 }
742
744 {
745 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
746 pin(),
748 108, // Get Last Total Effort
749 0x55,0x55,0x55,0x55
750 };
751 uint8_t rx[8];
752
753 _asosw.sendPacket(tx, rx);
754
755 int32_t returnVal;
756 memcpy(&returnVal,&rx[4],4);
757 return returnVal;
758 }
759
760 uint16_t ReadLastTarget()
761 {
762 uint8_t tx[] = { (uint8_t)SerialWombatCommands::CONFIGURE_PIN_OUTPUTSCALE,
763 pin(),
765 111, // Get Last Target
766 0x55,0x55,0x55,0x55
767 };
768 uint8_t rx[8];
769
770 _asosw.sendPacket(tx, rx);
771
772 return ((uint16_t)(rx[4] + 256 * rx[5]));
773 }
774
786 int16_t Enable2DLookupOutputScaling(uint16_t IndexInUserMemory
787 )
788 {
790 pin(),
792 10, // Set 2D Lookup Index
793 SW_LE16(IndexInUserMemory),0x55,0x55 };
794 return _asosw.sendPacket(tx);
795 }
796
798 virtual uint8_t pin() = 0;
800 virtual uint8_t swPinModeNumber() = 0;
801
802private:
803 SerialWombatChip& _asosw;
804
805};
806
807
#define SW_LE16(_a)
Convert a uint16_t to two bytes in little endian format for array initialization.
int16_t writeScalingEnabled(bool enabled, uint8_t sourcePin)
Enable scaling and set which pin or public data is used as the input source.
int16_t writeTimeout(uint16_t timeout_mS, uint16_t timeoutOutputValue)
Enable a timeout value which will cause the output to go to a default value if not updated.
int16_t writeEndstops(uint8_t endstop0Pin=0xFF, uint16_t endstop0TriggerValue=0x0000, uint16_t endstop0OutputValue=0x0000, bool endstop0GreaterThanOrEqual=false, uint8_t endstop1Pin=0xFF, uint16_t endstop1TriggerValue=0x0000, uint16_t endstop1OutputValue=0x0000, bool endstop1GreaterThanOrEqual=false)
Configure up to two endstop inputs which can override the Scaled Output value.
int16_t writeHysteresis(uint16_t lowLimit, uint16_t lowOutputValue, uint16_t highLimit, uint16_t highOutputValue, uint16_t initialOutputValue)
Controls the output based on hystersis control.
int16_t Enable2DLookupOutputScaling(uint16_t IndexInUserMemory)
Set Up 2D Lookup Output Scaling.
SerialWombatAbstractScaledOutput(SerialWombatChip &sw)
Constructor for the SerialWombatAbstractScaledOutput Class.
int16_t writeOutputScaling(uint16_t outputMin, uint16_t outputMax)
Reduces the output range from 0 to 65535 to user specified range.
int16_t writeRateControl(Period samplePeriod, uint16_t maximumChangecounts, uint16_t maximumDecrementCounts=0)
Controls how fast an ouput can change in counts.
int16_t writeRamp(uint16_t slowIncrement, uint16_t incrementThreshold, uint16_t fastIncrement, Period samplePeriod, RampMode rampMode)
Configure the scaled output block into Ramp control mode.
int16_t writeScalingTargetValue(uint16_t target)
The target input value for PID control.
virtual uint8_t pin()=0
Facilitates inheritance.
int16_t write1stOrderFiltering(Period samplePeriod, uint16_t filterConstant)
Controls how fast an ouput can change based on filtering.
uint16_t readLastOutputValue()
Request Last Output Value.
int16_t writeInputScaling(uint16_t inputMin, uint16_t inputMax)
Scale incoming values to a range of 0 to 65535.
int16_t writeScalingTargetValueResetIntegrator(uint16_t target)
int16_t writePID(uint16_t kp, uint16_t ki, uint16_t kd, uint16_t target, Period samplePeriod, uint8_t targetPin=255, bool biDirectional=false)
Configure the scaled output block into PID control mode.
int16_t writeScalingInvertedInput(bool inverted)
if enabled subtract the input value from 65535 before doing any other processing.
virtual uint8_t swPinModeNumber()=0
Facilitates inheritance.
Class for a Serial Wombat chip. Each Serial Wombat chip on a project should have its own instance.